2016-08-13 83 views
1

我想列出所有n個數字的排列組合。直到現在,一切似乎都正常,但我遇到了一個非常奇怪的行爲有了這個代碼:C for循環無法正常工作沒有printf

int **liste_permutations(int n){ 
    int i, fact = factorielle(n); 
    int **tab=malloc(sizeof(int*)*fact); 
    for(i=0; i<fact; ++i) 
    { 
      tab[i] = malloc(sizeof(int)*n); 
    } 
    for(i=0;i<n;++i) 
    { 
      tab[0][i] = n-i; 
    } 

    for(i=1;i<fact;++i) 
    { 
      tab[i] = next_permutation(tab[i-1], n); 
    printf(" "); 
    } 
    return tab;} 

的這個主()

int **tab; 
    tab = liste_permutations(3); 
    for(i=0; i<factorielle(3); ++i) 
    { 

      for(j=0; j<3; ++j) 
      { 
        printf("%d", tab[i][j]); 
      } 
      printf("\n"); 
    } 

輸出是

  321 
    231 
    213 
    312 
    132 
    123 

,但如果我將其更改爲

int **liste_permutations(int n){ 
    int i, fact = factorielle(n); 
    int **tab=malloc(sizeof(int*)*fact); 
    for(i=0; i<fact; ++i) 
    { 
      tab[i] = malloc(sizeof(int)*n); 
    } 
    for(i=0;i<n;++i) 
    { 
      tab[0][i] = n-i; 
    } 

    for(i=1;i<fact;++i) 
    { 
      tab[i] = next_permutation(tab[i-1], n); 
    } 
    return tab;} 

的輸出主要是:

321 
231 
321 
231 
321 
231 

如果我嘗試這樣做,N = 5爲例,(因爲它試圖輸出125「「大概)

這裏是next_permutation代碼的輸出是空白:

int *next_permutation(int *t, int n){ 
    //printf("n = %d\n", n); 
    int i, max, count; 
    for(i=0;(i<n) && (max !=i); ++i) 
    { 
      if(t[i] == n) 
      { 
        max = i; 

      } 
      if(t[i] == (t[i-1]+1)) 
      { 
        ++count; 
        if(count == (n-1)) 
        { 
          return NULL; 
        } 
      } 

    } 
    //printf("max = %d\n", max); 
    if(n==1) 
    { 
      //printf("n=1\n"); 
      return NULL; 
    } 
    int *next = malloc(n); 
    if(max == n-1) 
    { 
      //printf("max == n-1\n"); 
      int *s; 
      s = malloc(sizeof(int)); 
      for(i=0; i<(n-1);++i) 
      { 
        s[i]=t[i]; 
      } 
      for(i=0; i<n-1; ++i) 
      { 
        //printf("%d", s[i]); 
      } 
      //printf("\n"); 
      s = next_permutation(s, n-1); 
      if(s == NULL) 
      { 
        //printf("NUUUUUUl"); 
      //  next = NULL; 
        return NULL; 
      } 
      //printf("reprise en n = %d\n", n); 
      for(i=1;i<n;++i) 
      { 
        next[i] = s[i-1]; 
      } 
      //printf("\n"); 
      free(s); 
      next[0]=n; 
      return next; 
    } 
    else 
    { 
      //printf("max != n-1\n"); 

      for(i=0; i<n; ++i) 
      { 
        next[i] = t[i]; 
      } 
      int tmp = next[max]; 
      next[max] = next[max+1]; 
      next[max+1] = tmp; 
      for(i=0;i<n;++i) 
      { 
        //printf("%d", next[i]); 
      } 
      //printf("\n"); 
      return next; 
    }} 

編輯:修改了什麼2第一個評論說,但我仍然有山姆問題。

編輯2:謝謝你幫助我的每一個人!特別是mweerden誰給我指出了正確的道路(這是因爲計數是未初始化的)!

+1

你的'next_permutation'代碼正在向右和向左泄漏內存,更不要說'liste_permutations'中的所有初始分配:它們在重新賦值後也不見了。你不應該每次分配一個新的數組,你應該傳遞一個現有的數組作爲結果,例如'next_permutation(tab [i],tab [i-1],n)' – dasblinkenlight

+0

你想使用調試器來跟蹤代碼來學習究竟是怎麼回事。 – alk

+1

因爲你是新來的,我想給你一點提示。如果其中一個答案解決了您的問題,您應該接受該答案作爲正確答案。要接受答案,您可以點擊表決按鈕下方的小複選標記。這既增加了你的聲譽,也增加了幫助你的人的聲譽。 – Asthor

回答

2
tab[i] = malloc(sizeof(int*)*n); 

tab[i]想要的int秒的數組(不是int*秒的陣列)

更改爲

tab[i] = malloc(sizeof(int)*n); 

而且

int *s; 
for(i=0; i<(n-1);++i) 
{ 
    s[i]=t[i]; 
} 

你不爲預留空間s(使用未初始化)

+1

謝謝,我改變了它,但仍然有相同的行爲... 無論如何,謝謝你,我剛剛贏得了更好的音符,因爲你! –

1

這裏有很多錯誤。你開始好:

int **tab=malloc(sizeof(int*)*fact); 

但這是錯誤的:

for(i=0; i<fact; ++i) 
{ 
    tab[i] = malloc(sizeof(int*)*n); 
} 

它應該是:

tab[i] = malloc(sizeof(int)*n); // int, not int * 

然後,你next_permutation循環:

for(i=1;i<fact;++i) 
{ 
    tab[i] = next_permutation(tab[i-1], n); 
    printf(" "); 
} 

您已經已被分配到上面的- 在這裏你再做一次?

此外,在next_permutation本身,你有下面這行:

if(t[i] == (t[i-1]+1)) 

的問題是,i可以0 - 索引t[-1]是不是你想要做什麼!

2

printf語句具有這種效果的原因是因爲你使用的是可變max尚未初始化:

int i, max, count; 
for(i=0;(i<n) && (max !=i); ++i) 

當你不初始化它,將其值所剩下的有通過其他代碼,當這段內存是上次使用。如果您沒有printf聲明,則該值將是上一次致電next_permutation時所留下的任何值。如果printf在那裏,則該值將是由printf調用留下的某個值。除第一次致電next_permutation外,其餘值爲malloc