There are three types of edits that can be performed on strings: insert a character, remove a character, or replace a character.
EXAMPLES:
pale, ple returns true
pales, pale returns true
pale, bale returns true
pale, bake returns false
My solutions seems to work for any case I could think of (like ("", "s") but I feel like I'm checking conditions too much in it (mainly my final if/else statement had to be tacked on when I saw my solution wouldn't work for ("pales", "pale"))
bool oneAway(string s1, string s2)
{
//loop through smaller string size
decltype(s1.size()) size = (s1.size() < s2.size()) ? s1.size() : s2.size();
for (decltype(s1.size()) i = 0; i < size; ++i)
{
if (s1[i] != s2[i])
{
string temp1 = s1.substr(i + 1);
string temp2 = s2.substr(i + 1);
//if rest of the string is equal we do 1 replacement.
if (temp1 == temp2)
{
s1[i] = s2[i];
break;
}
//otherwise we will try to insert or remove a character
else
{
if (s1.size() < s2.size())
{
s1.insert(i, 1, s2[i]);
break;
}
else
{
s1.erase(i, 1);
break;
}
}
}
}
//check equality
if (s1 == s2)
return true;
//otherwise try to erase last character in s1 and check again (since for loop may not check this character if s2 was smaller string size)
else
{
s1.erase(s1.size() - 1, 1);
if (s1 == s2)
return true;
}
return false;
}
This question is from the book "Cracking the Code Interview" by Gayle McDowell.
std::mismatch
with the forward and reverse iterators, respectively). It's a simple comparison between the results to spot that you've reached the same position in one string or the other. The only catch is that forward iterators aren't directly comparable to the reverse iterators, so you need to usestd::make_reverse_iterator()
, or dereference and compare by identity (&*it1 == &*it2
). Or usebase()
. \$\endgroup\$