2017-10-06 98 views
0

*編輯追加到帖子的底部。爲什麼-doesn't-這個循環無休止地循環?

我試圖生成用C一些代碼,生成具有10行和2列的2D陣列。我創建了一個檢查,看看是否在生成一行時,如果它與另一個現有行相同,它將不斷更改其值,直到它爲新的唯一行。

我爲了驗證while循環不應該終止,因爲有不爲0和10個獨特的組合,1是它可能找到當前設置的最大變量,只有1。這段代碼確實發現了重複項,並相應地進行了更改,但似乎最終跳過了檢查並終止,而不是像應該那樣無休止地循環。 printf函數用於探測我的代碼的行爲。

爲什麼我while循環終止?

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <time.h> 

int main (int argc, char *argv[]) { 
    int max_x = 1, max_y = 1; 
    int num_pt = 10; 
    int array[num_pt][2]; 
    srand(time(0)); 

    //Generate a new file 
    if (argc == 1) { 
     printf("Generating instances\n"); 
     for (int i = 0 ; i < num_pt ; i++) { 
      array[i][0] = rand()%(max_y+1); 
      array[i][1] = rand()%(max_x+1); 
      for (int j = i-1 ; j >= 0 ; j--) { 
       while ((array[i][0] == array[j][0]) && (array[i][1] == array[j][1])) { 
        printf("\narray[%d][0]/[%d][1] and array[%d][0]/[%d][1]: Duplicate exists", i, i, j, j); 
        array[i][0] = rand()%(max_y+1); 
        array[i][1] = rand()%(max_x+1); 
       } 
      } 
     } 
     for (int j = 0 ; j < num_pt ; j++) { 
      printf("\nRow[%d] = [%d][%d]", j, array[j][0], array[j][1]); 
     } 
    return 1; 
    } 
} 

樣本輸出:

Generating instances 

array[2][0]/[2][1] and array[0][0]/[0][1]: Duplicate exists 
array[2][0]/[2][1] and array[0][0]/[0][1]: Duplicate exists 
array[3][0]/[3][1] and array[1][0]/[1][1]: Duplicate exists 
array[4][0]/[4][1] and array[1][0]/[1][1]: Duplicate exists 
array[5][0]/[5][1] and array[1][0]/[1][1]: Duplicate exists 
array[6][0]/[6][1] and array[4][0]/[4][1]: Duplicate exists 
array[6][0]/[6][1] and array[2][0]/[2][1]: Duplicate exists 
array[6][0]/[6][1] and array[0][0]/[0][1]: Duplicate exists 
array[7][0]/[7][1] and array[6][0]/[6][1]: Duplicate exists 
array[7][0]/[7][1] and array[0][0]/[0][1]: Duplicate exists 
array[8][0]/[8][1] and array[4][0]/[4][1]: Duplicate exists 
array[8][0]/[8][1] and array[2][0]/[2][1]: Duplicate exists 
array[8][0]/[8][1] and array[0][0]/[0][1]: Duplicate exists 
array[9][0]/[9][1] and array[8][0]/[8][1]: Duplicate exists 
array[9][0]/[9][1] and array[6][0]/[6][1]: Duplicate exists 
array[9][0]/[9][1] and array[6][0]/[6][1]: Duplicate exists 
array[9][0]/[9][1] and array[0][0]/[0][1]: Duplicate exists 
array[9][0]/[9][1] and array[0][0]/[0][1]: Duplicate exists 
Row[0] = [1][1] 
Row[1] = [1][0] 
Row[2] = [0][0] 
Row[3] = [0][1] 
Row[4] = [0][1] 
Row[5] = [0][0] 
Row[6] = [1][0] 
Row[7] = [0][0] 
Row[8] = [0][1] 
Row[9] = [0][1] 

------------------ 
(program exited with code: 1) 
Press return to continue 

感謝您的幫助。我終於明白了,因爲我昨晚躺在牀上想着它。我的解決方案是添加一個計數器,如果發現有任何冗餘的行,將重新運行整個檢查。

int main (int argc, char *argv[]) { 
    int max_x = 2, max_y = 2; 
    int num_pt = 9; 
    int array[num_pt][2]; 
    srand(time(0)); 
    int rerun = 1; 

    //Generate a new file 
    if (argc == 1) { 
     printf("Generating instances\n"); 
     for (int i = 0 ; i < num_pt ; i++) { 
      array[i][0] = rand()%(max_y+1); 
      array[i][1] = rand()%(max_x+1); 
      rerun++; 
      while (rerun != 0) { 
       rerun = 0; 
       for (int j = i-1 ; j >= 0 ; j--) { 
        if (array[i][0] == array[j][0] && array[i][1] == array[j][1]) { 
         printf("\narray[%d][0]/[%d][1] and array[%d][0]/[%d][1]: Duplicate exists", i, i, j, j); 
         array[i][0] = rand()%(max_y+1); 
         array[i][1] = rand()%(max_x+1); 
         rerun++; 
        } 
       } 
      } 
     } 
     for (int j = 0 ; j < num_pt ; j++) { 
      printf("\nRow[%d] = [%d][%d]", j, array[j][0], array[j][1]); 
     } 
    return 1; 
    } 
} 

這樣的作品,但如果任何人有這樣做,我所有的耳朵的更有效的方式。

+2

爲什麼不在調試器中逐行執行代碼?這樣你可以很容易地看到真正發生的事情。 –

回答

1

錯誤的循環順序。

你的內部循環,同時只保留了一遍又一遍檢查同一對,直到找到該特定對的有效組合。

當它,它很可能已經突破兼容性與其他元素雖然。由於你的外部和中間循環永遠不會重新訪問已經工作過一次的對,這完全沒有被注意到。

0

簡單,當你嘗試看看,如果行i和j行是相似的,你行改變i的值。

然後j = j - 1.現在您將這個新的j與第i行進行比較。如果這些情況恰好相似,那麼您再次更改第i行,但是這次您並未查看行j的先前值。

當您創建新行時,您必須記住每行的所有使用值。但是目前的算法一次只能看2行。

這是我講的,

 1 0 
j -- 0 1 
i -- 0 1 

row i == row j, change row i 

     1 0 
j -- 0 1 
i -- 1 0 

j --; 

j -- 1 0 
     0 1 
i -- 1 0 

row i == row j, change row i 

j -- 1 0 
     0 1 
i -- 0 1 

在此,循環中斷正確,因爲行i = j行,但該行我的情況 - 1還是類似於第i行。