Test whether the edit-distance of two strings is at most 1 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() &lt; s2.size()) ? s1.size() : s2.size();

    for (decltype(s1.size()) i = 0; i &lt; 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() &lt; 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.
It looks like you either imported std::string or the whole standard namespace into the global namespace.
It's ok to do the former in implementation-files, though I would desist as it doesn't gain you all that much in brevity.
If it's the latter, read "Why is “using namespace std;” considered bad practice?" and change it.
Avoid allocating memory. Doing so is slow and can fail. That means accepting the arguments by constant reference, not using temporary copies, and not modifying the arguments.
If you had C++17, it would mean changing to std::string_view for the added flexibility.
Prefer using auto to a more complicated expression using decltype. It's less error-prone, more readable, and also shorter.
&lt;algorithm&gt; contains std::min(). Using that is more readable, shorter and no less efficient than writing it out using the conditional-operator.
Did you test ("abc", "b")? That's two deletions edit-distance, but will be accepted anyway.
Keep your line-length reasonable. Horizontal scrolling kills readability.


Using all that, but staying true to C++11:

#include &lt;string&gt;
#include &lt;algorithm&gt;

bool oneAway(const std::string&amp; a, const std::string&amp; b) noexcept {
    if (a.size() &gt; b.size())
        return oneAway(b, a);
    if (b.size() - a.size() &gt; 1) // No need to look further, pure optimization
        return false;
    auto begin = std::mismatch(a.begin(), a.end(), b.begin());
    using reverse_it = decltype(a.rbegin()); // std::make_reverse_iterator is C++14
    auto end = std::mismatch(a.rbegin(), reverse_it(begin.first), b.rbegin());
    return end.second.base() - begin.second &lt; 2;
}


And for testing:

#include "one_away.h"
#include &lt;iostream&gt;
#include &lt;cstdlib&gt;

static bool do_test(const std::string&amp; a, const std::string&amp; b, bool expected) {
    bool r = oneAway(a, b);
    std::cout &lt;&lt; (r == expected ? "[OK] " : "[FAIL] ")
        &lt;&lt; std::boolalpha &lt;&lt; r &lt;&lt; " \"" &lt;&lt; a &lt;&lt; "\" \"" &lt;&lt; b &lt;&lt; \"\n";
    return r == expected;
}

static bool test(const std::string&amp; a, const std::string&amp; b = a, bool expected = true) {
    bool r = do_test(a, b, expected);
    if (a != b)
        r &amp;= do_test(b, a, expected);
    return r;
}

int main() {
    bool r = test("");
    r &amp;= test("abc");
    r &amp;= test("pale", "ple");
    r &amp;= test("pales", "pale");
    r &amp;= test("pale", "bale");
    r &amp;= test("pale", "bake", false);
    r &amp;= test("abc", "b", false);
    std::cout &lt;&lt; (r ? "[OK]\n" : "[FAIL]\n");
    return r ? 0 : EXIT_FAILURE;
}