2016-11-05 1 views
0

私はウェブで答えを見て、どのようにそのループで動作するのか理解していません。そして、なぜ私はうまくいかないのですか。質問:文字列s1の各文字を、文字列s2に一致する文字をすべて削除するsqueeze(s1,s2)の代替バージョンを作成します。 s1の各文字は、s2のすべての文字と一致しないことを確認する必要があります。文字がs1に表示されているように、s2をループして、その文字がs1に一致するかどうかを確認し、s1の次の文字に移動します。だからs1の外側ループとs2の内側ループ。 ここに彼のコードがあります。私はそれをテストするためのコード全体に入れました。彼の出力は正しい。彼のコードは機能の部分です。私が理解していないのは、彼が外側のループにs2を入れて、それが動作する理由です。Cプログラミング言語の演習2-4:私は答えを理解していません

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

void squeeze2(char s[], char t[]); 

void squeeze2(char s[], char t[]) { 
    int i, j, k; 
    for (k = 0; t[k] != '\0'; k++) { 
     for (i = j = 0; s[i] != '\0'; i++) 
      if (s[i] != t[k]) 
       s[j++] = s[i]; 
     s[j] = '\0'; 
    } 
} 

int main() { 
    char s1[] = "hello meow meow princess"; 
    char s2[] = { 'a', 'e', 'm' }; 
    squeeze2(s1, s2); 
    int i = 0; 
    while (s1[i] != '\0') { 
     printf("%c", s1[i]); 
     i++; 
    } 
} 

そしてtheres mine。それは実際にs2やあなたの周りには、実際に適応させることを提供する他の方法でs1と次に最初にあなたのループかどうかは関係ありません

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

void squeeze(char s1[],char s2[]); 

int main() { 
    char s1[] = "hello meow meow princess"; 
    char s2[] = { 'a', 'e', 'm' }; 
    squeeze(s1, s2); 
    int l; 
    for (l = 0; l < strlen(s1); l++) 
     printf("%c", s1[l]); 
} 

void squeeze(char s1[], char s2[]) { 
    int i = 0; 
    int k = 0; 
    while (s1[i] != '\0') 
     for (int j = 0; s2[j] != '\0'; j++) { 
      if (s1[i] != s2[j]) { 
       s1[k] = s1[i]; 
       k++; 
      } 
      i++; 
     } 
} 
+0

さまざまな変数を印刷するための印刷機能を持つコードと、コードフローを注意深く調べます。これは、2つのコードの違いについて、あなたに良い洞察を与えるかもしれません。 – Evert

+0

この状態は 's2 [j]!= '\ 0''が働いているのに驚きました。それから、 '-O3'でコンパイルし、バスエラーで失敗しました。 ''\ 0''はあなたの' s2'文字列に*ない*であるので、あなたはそれを比較してはいけません! (言い換えれば、どちらのバージョンの 'squeeze'も動作しません) – Evert

答えて

0

..私は、内のコードでS2を入れて、そのアウトプットはhlloニャー王女ニャーですコード。

問題は両方のバージョンである:2番目の文字列から文字が末尾を超えて間接参照されるようsqueezeでの動作が定義されていないので、main内の文字列s2は、(それがC文字列ではありません)NULL終端ではありません配列のあなたはヌルその文字の一つ以上がs2で発見された場合、それは短縮されます場合にs1を終了していない

  • は、お使いのバージョンでは多くの問題があります。

  • アルゴリズムが壊れている:s1の各文字をs2に一致しない文字が何回もコピーされます。

文字がstrchr(s2, s1[i])を呼び出すか、手で列挙のいずれかによって、s2に存在している場合は、代わりに確認する必要があります。

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

void squeeze(char *s1, const char *s2); 

int main(void) { 
    char s1[] = "hello meow meow princess"; 
    char s2[] = { 'a', 'e', 'm', '\0' }; 
    squeeze(s1, s2); 
    printf("%s\n", s1); 
    return 0; 
} 

void squeeze(char *s1, const char *s2) { 
    int i, j, k; 
    for (i = k = 0; s1[i] != '\0'; i++) { 
     for (j = 0; s2[j] != '\0'; j++) { 
      if (s1[i] == s2[j]) 
       break; 
     } 
     if (s2[j] == '\0') { // character was not found in s2 
      s1[k++] = s1[i]; 
     } 
    } 
    s1[k] = '\0'; // null terminate s1 of it was shortened 
} 

注:

  • 常にifelseforwhiledo ... while

  • 後に非自明な文の中括弧を使うここで

    を修正し、簡易版であります

    for以上:インデックス変数の初期化、増分、テストをグループ化することで、可読性が向上し、バグが減少します。

  • 変数名の変更を避けるl:固定幅フォントでは、1と似ています。

  • const修飾子は、関数によって変更されない引数です。

+0

ありがとう!あなたはそれがCの文字列ではないという意味ですか?すべての配列や文字列がcで目に見えない '\ 0'を持っているわけではありませんか? – jessie

+0

@jessie: 's2'を' s2 [] = "aem"; 'と定義したのですが、あなたはこれをちょうど3バイトだけこのようにしました。' char s2 [] = {'a'、 'e '、' m '};それはしません。 – chqrlie

関連する問題