【ブラシノート】LeetCode_28:strStr()を実現_簡単(C)
テーマ:strStrを実現する()
haystack文字列とneedle文字列を指定し、haystack文字列にneedle文字列が現れる最初の位置(0から)を見つけます.存在しない場合は、-1を返します.
例1:
入力:haystack=「hello」、needle=「ll」出力:2
例2:
入力:haystack=「aaaa」、needle=「bba」出力:-1
この問題では、needleが空の文字列である場合、0を返します.これはC言語のstrstr()およびJavaのindexOf()定義と一致する.
この問題は見たばかりの頃は簡単だと思っていたが、意外にも穴が多かった.の自分で書いたコードは以下の通りですが、正しいかどうかはわかりませんが、どうせタイムアウトです...
最初の構想は、haystackでスキャンしてneedleの頭文字を探し、見つからない場合は-1に戻ることです.見つけたら、その時の位置を記録し、スキャンし、次の文字がneedleの次の文字と同じであれば位置を返し、異なる場合はbreakがループし、-1を返します.
でも!この考えには抜け穴がある!!例:
入力:haystack=「missiissip」、needle=「issip」出力:5
この例では、needleの最初の文字は「i」なので、初めて現れた位置は1ですが、スキャンすると後ろの文字がneedleと合わないことがわかり、breakが出てきて-1に戻ります.これは間違っています!!あと一段あるので、またスキャン!!
だから私はまたjudge変数を設定して、breakが出てきたらi,j,flagの値を更新してスキャンして、次のhaystackの中でスキャンしていない文字がneedleに合っているかどうかを見ます.
でも!また問題が発生しました!!!最外層のwhileサイクルは最後にi++の動作があり、firstの位置を見つけることを制御する.しかしjudge=1の場合、firstが見つかった後、後ろの文字列がneedleと一致し、breakが値を更新してスキャンする必要がない場合、このときのiに1が加算され、addressもそれに応じて1が加算されます.だから私はi++をif(!judge)i++に変えましたが.タイムアウト...だから私は他の人のコードを見るしかありません..
以下は他人のコードを見て書いたACコードですが、n^2の複雑さは本当に遅いpで、振り返って大神の比較的速いアルゴリズムを見てみましょう.
この二層サイクルの暴力解法は、外層サイクル制御haystack、内層サイクル制御needle、外層はi=0から、内層はj=0から、haystack[i+j]がneedle[j]と異なるとbreakし、その後、i++がneedleの最初の文字と同じ位置を見つけるまで、このように推す.次の点に注意してください.
1.flagの値は更新を忘れないでください!!前のmissiissipの例が現れる可能性があるので,1回以上の内層forサイクルに入る必要がある.
2.if(!flag) return i; この文は内層サイクルが終わった後、外層サイクル内に書きます.内層サイクルが終了した後、flag=0の場合、マッチングに成功したことを示すため、直接return;flag=1の場合,さらにスキャンマッチング操作が必要であることを示し,この判断を外層サイクルの外に書けば正解は得られない.外層サイクル終了の条件はhaystackがすべてスキャン終了したためflagの値は言いにくい.
3.hayaystack[i+j]の理解.内層サイクルが入るたびにjは0に初期化されるので、needleは毎回最初から比較され、私の最初のコードを省くたびに手動で更新されますが、haystackでneedleの最初の文字と同じ文字位置が見つからないと、内層サイクルを実行できません.入るとbreakが出るからです.見つけたら内層ループを実行すると、i+jの値はj++とともに増加し、haystackの最初の文字の出現位置でneedle文字列と比較し始め、私の前の「i=j-1」の愚かな更新操作を省くことに相当する.
haystack文字列とneedle文字列を指定し、haystack文字列にneedle文字列が現れる最初の位置(0から)を見つけます.存在しない場合は、-1を返します.
例1:
入力:haystack=「hello」、needle=「ll」出力:2
例2:
入力:haystack=「aaaa」、needle=「bba」出力:-1
この問題では、needleが空の文字列である場合、0を返します.これはC言語のstrstr()およびJavaのindexOf()定義と一致する.
この問題は見たばかりの頃は簡単だと思っていたが、意外にも穴が多かった.の自分で書いたコードは以下の通りですが、正しいかどうかはわかりませんが、どうせタイムアウトです...
int strStr(char * haystack, char * needle){
char first;
int i = 0;
int j = 0;
int k = 1;
int length = strlen(haystack);
int num = strlen(needle);
int flag = 1;
int judge = 0;
int address;
if(needle[0] == '\0') return 0;
if(length < num) return -1;
first = needle[0];
while(haystack[i] != '\0')
{
if(haystack[i] == first)
{
address = i;
for(j=i+1; k<num; j++)// num ok
{
if(haystack[j] != needle[k])// needle
{
flag = 0;
break;
}
k++;
}
if(!flag) // break , haystack needle num
{
i = j-1;// num needle, , i
k = 1;// k=1
flag = 1;// flag
}
else judge = 1;// break needle
}
i++; // judge, , i++ 1
}
if(!judge) return -1;
else return address;
}
最初の構想は、haystackでスキャンしてneedleの頭文字を探し、見つからない場合は-1に戻ることです.見つけたら、その時の位置を記録し、スキャンし、次の文字がneedleの次の文字と同じであれば位置を返し、異なる場合はbreakがループし、-1を返します.
でも!この考えには抜け穴がある!!例:
入力:haystack=「missiissip」、needle=「issip」出力:5
この例では、needleの最初の文字は「i」なので、初めて現れた位置は1ですが、スキャンすると後ろの文字がneedleと合わないことがわかり、breakが出てきて-1に戻ります.これは間違っています!!あと一段あるので、またスキャン!!
だから私はまたjudge変数を設定して、breakが出てきたらi,j,flagの値を更新してスキャンして、次のhaystackの中でスキャンしていない文字がneedleに合っているかどうかを見ます.
でも!また問題が発生しました!!!最外層のwhileサイクルは最後にi++の動作があり、firstの位置を見つけることを制御する.しかしjudge=1の場合、firstが見つかった後、後ろの文字列がneedleと一致し、breakが値を更新してスキャンする必要がない場合、このときのiに1が加算され、addressもそれに応じて1が加算されます.だから私はi++をif(!judge)i++に変えましたが.タイムアウト...だから私は他の人のコードを見るしかありません..
以下は他人のコードを見て書いたACコードですが、n^2の複雑さは本当に遅いpで、振り返って大神の比較的速いアルゴリズムを見てみましょう.
int strStr(char * haystack, char * needle){
int length = strlen(haystack);
int num = strlen(needle);
int flag = 0;
int i,j;
if(needle[0] == '\0') return 0;
if(length <num) return -1;
for(i=0; i<length; i++)
{
flag = 0;
for(j=0; j<num; j++)
{
if(haystack[i+j] != needle[j])
{
flag = 1;
break;
}
}
if(!flag) return i;
}
return -1;
}
この二層サイクルの暴力解法は、外層サイクル制御haystack、内層サイクル制御needle、外層はi=0から、内層はj=0から、haystack[i+j]がneedle[j]と異なるとbreakし、その後、i++がneedleの最初の文字と同じ位置を見つけるまで、このように推す.次の点に注意してください.
1.flagの値は更新を忘れないでください!!前のmissiissipの例が現れる可能性があるので,1回以上の内層forサイクルに入る必要がある.
2.if(!flag) return i; この文は内層サイクルが終わった後、外層サイクル内に書きます.内層サイクルが終了した後、flag=0の場合、マッチングに成功したことを示すため、直接return;flag=1の場合,さらにスキャンマッチング操作が必要であることを示し,この判断を外層サイクルの外に書けば正解は得られない.外層サイクル終了の条件はhaystackがすべてスキャン終了したためflagの値は言いにくい.
3.hayaystack[i+j]の理解.内層サイクルが入るたびにjは0に初期化されるので、needleは毎回最初から比較され、私の最初のコードを省くたびに手動で更新されますが、haystackでneedleの最初の文字と同じ文字位置が見つからないと、内層サイクルを実行できません.入るとbreakが出るからです.見つけたら内層ループを実行すると、i+jの値はj++とともに増加し、haystackの最初の文字の出現位置でneedle文字列と比較し始め、私の前の「i=j-1」の愚かな更新操作を省くことに相当する.