2016-03-23 13 views
-3

"文字列s1の最初の場所を文字列s2の任意の文字が出現するs1の位置に返す関数any(s1、s2) 。K&R演習2-5、エラー制御が非空白関数の終わりに達する可能性があります

int any(string a,string b){ 
    int i,j; 
    int c = 0; 
    for(i=0;i<strlen(a);i++){ 
     for(j=0;j<strlen(b);j++){ 
      if(b[j]==a[i]&&c==0){ 
       c = 1; 
       return i; 
       break; 
      } 
     } 
    } 

    if(c==0) 
    return -1; 
} 
+0

あなたは疑問を持っていますか? – juanchopanza

+2

不完全なコードですが、最後のテストは私がfalseである場合、コントロールは値を返さずに関数の最後に到達します。少なくともコンパイラは 'c'が必ず0であることを知ることができません。 –

+1

なぜ' c'変数が必要ですか?それを削除しようとします。また、復帰後にブレークする必要はありません –

答えて

1

あなたがに開始する必要があります:私は私のコードをコンパイルするときs1がs2の からの文字が含まれていない場合は-1、私はコントロールがエラーを引き起こし非空function.which部の端に到達する可能性」を得る、ここに私のコードですブラケットを使用する方法を教えてください。これは、これを変更した場合、次のようになります。

これに

if(c==0){ 
    return -1; 
} 

あなたは簡単に何returnC != 0場合が存在しないことを発見するでしょう。

もう一つの問題はここにある:

if(b[j]==a[i]&&c==0){ 
    c = 1; 
    return i; 
    break; 
} 

まずあなたが本当に、return i;、その後breakを言うの?あなたが比較している

for(j=0;j<strlen(b);j++) 

:ここ

for(i=0;i<strlen(a);i++) 

と:ここにいることを意味している

size_t strlen(const char * str){ 
    const char *s; 
    for (s = str; *s; ++s) {} 
    return(s - str); 
} 

size_tlong unsigned intです:

もう一つは、およそ次のように定義されてstrlenですの これは、この行ことを意味します

int i,j; 

は次のようになります。

size_t i,j; 

か:だから

long unsigned i,j; 

あなたが必要ないくつかのキャストがまだあることを修正した場合でも:

int any(string a,string b){ 
    size_t i,j; 
    int c = 0; 
    for(i=0;i<strlen(a);i++){ 
     for(j=0;j<strlen(b);j++){ 
      if(b[j]==a[i]&&c==0){ 
       c = 1; 
       break; 
      } 
     } 
    } 

    if(c==1){ 
     return (int)i; 
    }else{ 
     return (int)-1; 
    } 
} 

プログラム全体を別のやり方で書くことを再考すべきであるということです。

多分これはあなたのために[OK]を次のようになります。

size_t any(string a,string b){ 
    size_t i,j; 
    int c = 0; 
    for(i=0;i<strlen(a);i++){ 
     for(j=0;j<strlen(b);j++){ 
      if(b[j]==a[i]&&c==0){ 
       c = 1; 
       break; 
      } 
     } 
    } 

    if(c==1){ 
     return i; 
    }else{ 
     return 1; 
    } 
} 
+0

ありがとう、これは本当に役立つ、私はそれに気付かない。 – user6106588

0

コンパイラはあなたがテストを得ればc == 0が真でなければならないことを理解することは十分にスマートではありませんので、あなたがエラーを取得しています。同じ理由から、テストは完全に不要なので、それを削除してその時点で-1を返すだけでエラーが修正されます。

あなたがに変更することにより、大幅に簡素化することができます。これは、冗長検査(複数可)を回避

int any(char * a, char * b){ 
    int i, j; 

    for(i = 0; a[i]; ++i) { 
     for(j = 0; b[j]; ++j) { 
      if(b[j] == a[i]) { 
       return i; 
      } 
     } 
    } 

    return -1; 
} 

、完全にあなたのc変数の必要性を回避し、strlen()に無償と繰り返し呼び出しを避けることができます。

typedef ing char *stringもやや味が悪い。

おそらく、この練習では、効率が上がるためにメモリの効率を交換することによって、配列をルックアップテーブルとして設定し、bの文字を読み取ってa終了するか、一致する。これはbの文字を正確に1回、多くても1回の完全なトラバーサルをaまで通過させる必要があるため、現在の2次時間ではなく、線形時間アルゴリズムを取得します。例えば

:出力と

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 

int any(char * a, char * b); 

int main(void) 
{ 
    printf("'rifle', 'flog': %d\n", any("rifle", "flog")); 
    printf("'pterodactyl', 'dint': %d\n", any("pterodactyl", "dint")); 
    printf("'xyzzy', 'fish': %d\n", any("xyzzy", "fish")); 

    return 0; 
} 

int any(char * a, char * b) 
{ 
    int lookup[CHAR_MAX + 1] = {0}; 

    for (int i = 0; b[i]; ++i) { 
     lookup[b[i]] += 1; 
    } 

    for (int i = 0; a[i]; ++i) { 
     if (lookup[a[i]]) { 
      return i; 
     } 
    } 

    return -1; 
} 

[email protected]:~/Documents/src/sandbox$ ./any 
'rifle', 'flog': 2 
'pterodactyl', 'dint': 1 
'xyzzy', 'fish': -1 
[email protected]:~/Documents/src/sandbox$ 
関連する問題