2012-03-26 10 views
-1

配列から重複した値を削除するプログラムを作成しています。最初に選択ソートソートメソッドを実行し、配列を変更してサイズを返す関数removedup()を呼び出します。次に、基本的に配列の値をそのサイズまで印刷します。しかし、私はそれを実行すると、元の配列だけを印刷し、次に空白スペースを印刷します。誰がなぜこれが起こっているのか知っていますか?Cの配列から重複する整数を取り除く

マイコード:http://pastebin.com/uTTnnMHN

ちょうど重複コード:

int removedup(int a[]) 
{ 
    int i, count, j; 
    count = n; 
    for (i = 0; i < (n - 1); i++) { 
     if (a[i] == a[i + 1]) { 
      for (j = 0; j < (n - i); j++) { 
       a[j] = a[j + 1]; 
      } 
      count--; 
      i--; 
     } 
    } 
    return count; 
} 
+0

個別にデバッグすることをおすすめします。出力ルーチンが動作することを確認してください。ソートルーチンが動作することを確認してください。 de-dupルーチンが動作することを確認してください。 (それは私には一番スケッチに見えます) – sarnold

+0

GetIntegerルーチンをscanfで置き換えなければなりませんでしたが、一度やりましたが、ソートされた配列はうまく印刷されました。ただし、重複があった場合、removedupから戻ったことはありません。並べ替える前に配列を印刷するとどうなりますか? –

+0

[アルゴリズム:配列から重複した整数を効率的に削除する方法](http://stackoverflow.com/questions/1532819/algorithm-efficient-way-to-remove-duplicate-integers-from-an-array) – Caleb

答えて

2

-1(J = 0; jの<(NI); J ++)のための

は、あなたのループをすることですシフトして配列を残して(重複した値を取り除いて)jをjにするのではなく、iにして、条件が正しくないようにしてください。

正しいものは

for(j=i;j<n-1;j++) 
{ 
    a[j]=a[j+1]; 
} 
a[n-1] = 0; // Because you shift your table to the left, the last value should not be used 
1

最初私は=、あなたが移動を開始するには0とあなたの重複除去機能は、[I] == A [I + 1]の場合、私= -1

for(i=0;i<(n-1);i++) 
{ 
     if(a[i]==a[i+1]) 
     {      
      for(j=0;j<(n-i);j++) 
      { 
       a[j]=a[j+1]; 
      } 
      count--; 
      i--; //i=-1 if(a[i]==a[i+1]) && if(i==0) 
     } 
} 
+0

しかし、それは次のループの前に+1されるので、それは= 0でしょうか? – Joshpho

1

必要がある場合ループはiにあり、両方のループのループバインドとしてcount - 1を使用する必要があります。そうでない場合は、重複があるたびに無限ループが発生します。これは最初の移動ループの後に常にがあるためです。

int removedup(int a[]) 
{ 
    int i, count, j; 
    count = n; 
    for(i = 0; i < (count-1); i++) 
    { 
     if(a[i] == a[i+1]) 
     { 

      for(j = i; j < (count-1); j++) 
      { 
       a[j]=a[j+1]; 
      } 
      count--; 
      i--; 
     } 
    } 
    return count; 
} 

が正しく機能します。

+0

しかしcountは、変更された配列のサイズを表します。私が毎回ループの中でそれを減らすと、それは正確ではないでしょう。なぜなら、すべての値を移動するだけでいいからです。 – Joshpho

+0

重複が見つかった後に配列の「末尾」を移動するたびに、それを減らすことは正しいことです。なぜなら、あなたは道徳的に配列から要素を1つ削除するので、それは1つ短くなります。そして、両方のループは、配列内の現在の要素数で停止する必要があります。 –

+0

このようなifステートメント内で値を減らすことを意味しますか? http://pastebin.com/SsBRL25B – Joshpho

0

とにかく別の配列を作成しているので、関数を単純化してみませんか?

その後
int removedup(int a[], int b[]) 
{ 
    int i; 
    int count = 1; 
    b[0] = a[0] 


    for(i=1;i<(n-1);i++){ 
     if(a[i-1] != a[i]){ 
      b[count++] = a[i]; 
     } 
    } 
    return count;       
} 

あなたはこの1つについて、ソートしかしtraverse.finallyせずに、配列の実効値を表示し、そのサイズを返す何

count=removedup(a, OutArray); 
0
int removedup(int a[]) 
{ 
    int i; 
    count = n; 
    for (i = 0; i < (count-1); ++i) { 
     if (a[i] == a[i+1]) { /* found a duplicate */ 
      int d = 0; /* count the duplicates */ 
      do { 
       ++d; 
      } while ((i+1+d) < count && a[i] == a[i+1+d]); /* probe ahead again for a duplicate */ 

      /* at this point we have either run out of duplicates or hit the end of the array */ 
      if ((i+1+d) < count) 
       memmove(&a[i+1], &a[i+1+d], sizeof(int)*(count-(i+1+d))); /* shift down rest of the array if there's still elements to look at */ 
      count -= d; /* adjust the count down by the number of duplicates */ 
     } 
    } 
    return count; 
} 
0

、関数を呼び出します。

int removedup(int a[]) 
{ 
    int i, count, j; 
    count = n; 
    int b[n]; 
    memset(b,0,sizeof(b)); 
    for (i = 0; i < (n - 1); i++) 
    { 
     if (-1 != b[i]) 
     { 
      for(j=i+1;j<n-1;j++) 
      { 
       if(a[i]==a[j]) 
       { 
        b[j]=-1; 
        count--; 
       } 
      } 
     } 
    } 
    for(i=0;i<n-1;i++) 
    { 
     if(-1 != b[i]) 
     { 
      printf("%d ",a[i]); 
     } 
    } 
    return count; 
}