2017-05-28 3 views
2

C newbをもう一度返します。私はKとR Cでエクササイズに手を入れています。そしてエクササイズを試してみると、私は本当に困っています。 私の解決策は機能しますが、必ずしも正しいとは限りません。私が書いたものを洗練するための助けを求めていますか、より良い(理解しやすい!)方法があれば! マイスクリプト:配列内のユニークな要素を抽出する(KとR C ex1-14から)

#include <stdio.h> 

/* How many times a character appears in an array */ 
main() 
{ 
    int c; 
    int count = 0; 
    int uniquecount = 0; 
    char array[20]; 
array[0] = '\0'; 

while((c = getchar()) != EOF) 
{ 
    array[++count] = c; 
} 

/* for each element in array, 
* check if array[each] in newarray. 
* if array[each] in newarray 
* break and start checking again. 
* if array[each] not in newarray 
* add array[each] to end of newarray*/ 

printf("count = %d\n", count); 
array[count] = '\0'; 
char newarray[count]; 
newarray[0] = '\0'; 

for(int a = 0; a < count; ++a) 
{ 
    for(int b = 0; b <= a; ++b) 
    { 
     if(newarray[b] == array[a]) 
      break; 
     if(newarray[b] != array[b]) 
     { 
      newarray[b] = array[b]; 
      ++uniquecount; 
     } 

    } 
} 

printf("uniquecount = %d\n", uniquecount);  
newarray[uniquecount + 1] = '\0'; 

printf("array => "); 
for(int i = 0; i < count; ++i) 
    printf("\'%c\'", array[i]); 
printf("\n"); 
printf("newarray => "); 
for(int i = 0; i < uniquecount + 1; ++i) 
{ 
    if(newarray[i] != '\0') 
     printf("\'%c\'", newarray[i]); 
} 
printf("\n"); 

} 

私はいくつかの単純な文字列をしようとすると、それが動作し、時にはそれがdoesntの:

./times_in_array 
this is 
count = 9 
uniquecount = 5 
array => '''t''h''i''s'' ''i''s'' ' 
newarray => 't''h''i''s'' ' 
./times_in_array 
something comes 
count = 16 
uniquecount = 11 
array => '''s''o''m''e''t''h''i''n''g'' ''c''o''m''e''s' 
newarray => 's''o''m''e''t''h''i''n''g'' ''c' 
./times_in_array 
another goes 
count = 13 
uniquecount = 12 
array => '''a''n''o''t''h''e''r'' ''g''o''e''s' 
newarray => 'a''n''o''t''h''e''r'' ''g''o''e''s' 

誰かが私が間違っているところに私を導くことができますしてください?どうもありがとう!

+0

秒は '内側のループの後もif'should。 – wildplasser

答えて

1

ほとんどの場合、main()の代わりにint main(void)と書いています。

また、それはあなたがこのようなあなたの新しい配列にアクセスしているときということを理解することは非常に重要です:あなたが実際に初期化されていないメモリにアクセスしている

newarray[b] 

。しかし、一致するランダムな文字がある可能性はarray[a]であり、小さすぎると離れてしまうようです。私はあなたがこのように、あなたの新しい配列を初期化することを示唆しているため

for(int i = 0; i < count; ++i) 
    newarray[i] = '\0'; 

さて、代わりに私の解決策を提供するので、私はあなたが間違っていたかを理解することを主張します。それは自分が教育している方法です。あなたはこのように、独自のカウンタを増加させたときにメッセージを

printf("b = %d, a = %d, newarray[b] = %c, array[a] = %c, array[b] = %c\n", b, a, newarray[b], array[a], array[b]); 

と印刷:例えば、次のように、内側のループの開始時に、あなたのデータを印刷するために、本当に参考になります

printf("UNIQUE, %d\n", uniquecount); 

プログラムを実行すると、次のように表示されます。

... 
b = 9, a = 12, newarray[b] = g, array[a] = s, array[b] = g 
b = 10, a = 12, newarray[b] = , array[a] = s, array[b] = o 
UNIEUQ, 10 
b = 11, a = 12, newarray[b] = , array[a] = s, array[b] = e 
UNIEUQ, 11 
b = 12, a = 12, newarray[b] = , array[a] = s, array[b] = s 
UNIEUQ, 12 
uniquecount = 12 
array => '''a''n''o''t''h''e''r'' ''g''o''e''s' 
newarray => 'a''n''o''t''h''e''r'' ''g''o''e''s' 

これは間違ったことを強く示唆しています。 's'(最後の文字)が最初にユニークなものとして見つかった(これはうまい)ので、ループを壊さないため、コードは新しい配列をチェックし続け、これがだまされる再びユニーク。

ですから、ユニークな要素を見つけたときにブレークを追加し、あなたはしばらくの罰金する必要があります:

++uniquecount; 
break; 
+1

ありがとう、あなたの助けは非常に貴重です。あなたに心から感謝してます。 – Sina

1

あなたは、各重複要素の一つのコピーが欲しい想定配列

a) sort it 
b) mark element one as unique 
v) iterate over it from i = 1 to i = N-1 and mark an element as unique if array[i-1] != array[i] 

のユニークな要素を取得します。重複する要素を排除するには、その上にある要素と同じでない要素を探すアルゴリズムを修正します。

コードに間違った文字列比較があります。

+0

ありがとうございます、あなたは絶対に正しいです。しかし、私はチャプター構造の枠内にとどまり、教えられた概念を進めようとはしていません。私はまだCでソートする方法を知らない! – Sina

関連する問題