[英]How to get longest line of 1's in array/matrix
我的任務是在陣列中找到1的“最長線”。 水平和垂直。 數組僅由0和1組成,例如如下所示:
4 4
0 1 1 1
0 1 0 1
0 1 1 0
1 0 1 0
輸出應打印[i] [j]為“開始”1,[i] [j]為“結束”1.所以水平應為[1] [0] [3] [0]。
我正在使用我的getcolor()函數來獲取[i] [j]點的值。
我在為WAAAAY考慮這個問題很長一段時間,花了將近一整周的時間。我有一些想法,但都沒有效果。 也許是因為我是C的新手並且對數組來說是全新的。
我知道我應該通過數組,每1個發現它應該將坐標保存為“start”,然后轉到下一個,將每1個發現保存到“end”。 找到0后,比較長度,如果長度最大,則覆蓋長度。 但我沒有設法正確編寫代碼。 有人可以幫我寫廣告代碼嗎? 非常感謝你。
編輯:這就是我所擁有的,但我只是在開始時它已經不起作用了:
if(arr != NULL) {
while (j < arr->cols) {
while (i <=arr->rows) {
if (getcolor(arr, i, j) == 1) {
startI = i;
startJ = j;
break;
}
else
i++;
}
i=0;
while (i <=arr->rows) {
if (getcolor(arr, i, j) == 1) {
endI = i;
endJ = j;
}
i++;
}
i=0;
printf("start %d %d\nend %d %d\nline %d\n\n", startI, startJ, endI, endJ, line);
j++;
}
}
當你遇到這樣的問題時,有助於將其分解為更容易解決的小問題。 你的問題就是一個很好的例子。 看起來你正試圖立刻解決整個問題,正如你所看到的那樣,嵌套循環和所有問題都會變得有點毛茸茸。 那么,你怎么能讓問題變得更簡單呢? 好吧,如果你能抓住你的手指並在一行上找到最長的線條,那就更簡單了。 同樣,有一個簡單的方法來獲得單列中最長的行是很好的。 所以,考慮編寫這樣的函數:
int longestLineInRow(int board[][], int width, int height, int &start, int &end)
{
// returns length, with start and end being the indices of the beginning and end of the line
}
int longestLineInColumn(int board[][], int width, int height, int &start, int &end)
{
// returns length, with start and end being the indices of the beginning and end of the line
}
現在很容易找到具有最長行的行:您只需找到每行中最長的行,然后選擇返回最大值的行。 列相同。
我還沒有解決為你找到行或列中最長行的問題,但這是一個更簡單的任務,一旦你不再嘗試解決整個問題,你可以自己解決。
對不起,為時已晚。 我沒有按照你想要的方式寫出它,但這確實會對你有所幫助。 只要閱讀它,你就會明白這一點。
鏈接到代碼http://pastebin.com/vLATASab
或者在這里查看:
#include <stdio.h>
main()
{
int arr[4][4];
arr[0][0] = 0;arr[0][1] = 1;arr[0][2] = 1;arr[0][3] = 1;
arr[1][0] = 0;arr[1][1] = 1;arr[1][2] = 0;arr[1][3] = 1;
arr[2][0] = 0;arr[2][1] = 1;arr[2][2] = 1;arr[2][3] = 0;
arr[3][0] = 1;arr[3][1] = 0;arr[3][2] = 1;arr[3][3] = 1;
int i, j, k;
int line, line_start, line_end, line_max = 0;
int col, col_start, col_end, col_max = 0;
// Horizently
for (k=0; k<4; k++)
{
for (i=0; i<4; i++)
{
if (!arr[k][i]) continue;
for (j=i; j<4; j++)
{
if (!arr[k][j]) break;
}
j--;
if (j-i+1>line_max)
{
line = k;
line_start = i;
line_end = j;
line_max = line_end-line_start+1;
}
}
}
printf("horizontaly\n");
printf("start: [%d][%d]\n", line, line_start);
printf("end: [%d][%d]\n", line, line_end);
// Verticaly
for (k=0; k<4; k++)
{
for (i=0; i<4; i++)
{
if (!arr[i][k]) continue;
for (j=i; j<4; j++)
{
if (!arr[j][k]) break;
}
j--;
if (j-i+1>col_max)
{
col = k;
col_start = i;
col_end = j;
col_max = col_end-col_start+1;
}
}
}
printf("\nverticaly\n");
printf("start: [%d][%d]\n", col_start, col);
printf("end: [%d][%d]\n", col_end, col);
}
我假設您顯示的功能只有問題的一半,即找到最長的1s垂直序列。 您必須編寫鏡像函數才能找到最長的水平序列。
我會告訴你我在你的方法中看到的錯誤:
while (i <=arr->rows)
應該是while (i < arr->rows)
,否則當你只有0,1,2和3 while (i < arr->rows)
,你也會看到第4行。 i
。 i
應該繼續前進 startJ
保存j
,但只要你檢查同一列, j
就不會改變 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct field {
int rows;
int cols;
int *field;
} Field;
Field init_Field(){//Mock
Field f;
int data[4][4] = {
{0, 1, 1, 1},
{0, 1, 0, 1},
{0, 1, 1, 0},
{1, 0, 1, 0}
};
f.rows = 4;
f.cols = 4;
int size = f.rows * f.cols;
f.field = malloc(size * sizeof(*(f.field)));
memcpy(f.field, data, size*sizeof(*(f.field)));
return f;
}
int getcolor(Field *f, int r, int c){
if(r < 0 || r >= f->rows) return -1;
if(c < 0 || c >= f->cols) return -1;
return f->field[ r * f->cols + c];
}
int search(Field *f, int r, int c, int dr, int dc, int level, int maxLen, int nowMax){
//dr,dc : incremental
if(dr > 0 && f->rows - r + level <= nowMax) return -1;//stop search
if(dc > 0 && f->cols - c + level <= nowMax) return -1;//stop search
if(level == maxLen)
return level;
if(getcolor(f, r, c)==1)
return search(f, r + dr, c + dc, dr, dc, level + 1, maxLen, nowMax);
return level;
}
int main(){
Field f = init_Field();
int HMaxLen = 0, HMaxRow, HMaxCol;
int RMaxLen = 0, RMaxRow, RMaxCol;
int r, c, len;
for(r = 0; r < f.rows;++r){
for(c = 0; c < f.cols;++c){
len = search(&f, r, c, 0, 1, 0, f.cols, HMaxLen);
if(len > HMaxLen){
HMaxLen = len;
HMaxRow = r;
HMaxCol = c;
}
len = search(&f, r, c, 1, 0, 0, f.rows, RMaxLen);
if(len > RMaxLen){
RMaxLen = len;
RMaxRow = r;
RMaxCol = c;
}
}
}
free(f.field);
printf("start %d %d\n end %d %d\n\n", HMaxRow, HMaxCol, HMaxRow, HMaxCol + HMaxLen-1);
printf("start %d %d\n end %d %d\n\n", RMaxRow, RMaxCol, RMaxRow + RMaxLen-1, RMaxRow);
return 0;
}
你可以試試以下
void Reset(int s[2], int e[2], int cs[2], int ce[2], int *resetState, int cc, int pc)
{
*resetState=0;
if(cc>pc)
{
s[0]=cs[0];
s[1]=cs[1];
e[0]=ce[0];
e[1]=ce[1];
}
}
void Decide(int value, int s[2], int e[2], int cs[2], int ce[2], int *resetState, int *cc, int *pc, int i, int j)
{
if(value==0&&*resetState)
{
Reset(s, e, cs, ce, resetState, *cc, *pc);
}
else if(value)
{
if(*resetState==0)
{
cs[0]=i;
cs[1]=j;
if(*cc>*pc)
{
*pc=*cc;
}
*cc=0;
*resetState=1;
}
ce[0]=i;
ce[1]=j;
++*cc;
}
}
void FindLargestRowNdColumn(int a[20][20],int row, int col, int hs[2], int he[2], int vs[2], int ve[2])
{
int i, j, rcc=0, rpc=0, ccc=0, cpc=0;
int chs[2]={0,0}, che[2]={0,0}, cvs[2]={0,0}, cve[2]={0, 0};
int resetRow=0, restCol=0;
for(i=0; i<row; ++i)
{
for(j=0; j<col; ++j)
{
Decide(a[i][j], hs, he, chs, che, &resetRow, &rcc, &rpc, i, j);
Decide(a[j][i], vs, ve, cvs, cve, &restCol, &ccc, &cpc, i, j);
}
Reset(hs, he, chs, che, &resetRow, rcc, rpc);
Reset(vs, ve, cvs, cve, &restCol, ccc, cpc);
}
}
void main()
{
int a[20][20], indexRow, colIndex;
int colum, row,hs[2], he[2], vs[2], ve[2];
printf("Enter number of rows and columns\n");
scanf("%d%d", &row, &colum);
printf("Enter the array\n");
for(indexRow=0; indexRow<row; ++indexRow)
{
for(colIndex=0; colIndex<colum; ++colIndex)
{
scanf("%d", &a[indexRow][colIndex]);
}
}
FindLargestRowNdColumn(a, row, colum, hs, he, vs, ve);
printf("Row [%d][%d] [%d][%d]\n", hs[0], hs[1], he[0], he[1]);
printf("column [%d][%d] [%d][%d]\n", vs[0], vs[1], ve[0], ve[1]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.