2つの文字列は1回の変換で等しくなるか
問題
2つの文字列が与えられた際に、1回の変換(文字の追加、削除、置き換え)で等しくなるか
考え方
文字列の長さが等しい時は1文字だけ違ったら、置き換えで対応できます。
str1[i] != str2[i]
となる数を判定して、これが1以下ならture。
文字列の長さが異なる時は、まず、1文字の差だけか確認します。
少ない方の文字列(M)が長い方の文字列(N)の中に順番通りに入っているか確認します。
どうするのが効率がいいかわからないですが、i:0->N-1
として、少ない方の文字列のindexj
をstr1[j] == str2[i]
の時にインクリメントして最後にj == M
ならtrue
とします。
どれにも適さないなら、false
を返します。
計算量
時間計算量はO(N)
ですみます。
コード例
#include<iostream> using namespace std; bool add(string str1, string str2){ // str1.length > str2.length()で入れる int i, j; j = 0; if(str1.length() < str2.length()){ cout << "使い方が違います!" << endl; }else{ for(i=0; i<str1.length(); i++){ if(str1.substr(i, 1)==str2.substr(j, 1)){ j++; } } if(j==str2.length()){ return true; } } return false; } bool check(string str1, string str2){ int i, j, n, m; string s; n = str1.length(); m = str2.length(); // N < M j = 0; if(n-1 == m){ return add(str1, str2); }else if(n == m-1){ return add(str2, str1); }else if(n==m){ for(i=0; i<m; i++){ if(str1.substr(i, 1)!=str2.substr(i, 1)){ j++; } } if(j<=1){ return true; } } return false; } int main(void){ bool flg; string str1 = "apple"; string str2 = "abnple"; flg = check(str1, str2); cout << "一回の変換で良いか? " << boolalpha << flg << endl; return 0; }
参考
問題は 世界で闘うプログラミング力を鍛える本 | マイナビブックス から。