Skip to main content
Added second version following Deduplicators suggestions
Source Link
miscco
  • 4.3k
  • 11
  • 17

Edit

Here a take at @Deduplicators suggestion, I didnt see that std::mismatch returns a pair of iterators, so it is really nice and doesnt even require reverse iterators

bool oneAway(const string& s1, const string& s2)
{
    if (s2.size() > s1.size()) {
       return oneAway(s2, s1);
    }
    
    // From here s1.size() >= s2.size()
    if (s1.size() - s2.size() > 1) {
       return false;
    }
        
    auto res = std::mismatch(s2.begin(), s2.end(), s1.begin());
    if (res.first== s2.end()) {
        return true;
    }

    res = std::mismatch(res.first, s2.end(), ++res.second);
    if (res.first== s2.end()) {
        return true;
    }
    return false;
}

Edit

Here a take at @Deduplicators suggestion, I didnt see that std::mismatch returns a pair of iterators, so it is really nice and doesnt even require reverse iterators

bool oneAway(const string& s1, const string& s2)
{
    if (s2.size() > s1.size()) {
       return oneAway(s2, s1);
    }
    
    // From here s1.size() >= s2.size()
    if (s1.size() - s2.size() > 1) {
       return false;
    }
        
    auto res = std::mismatch(s2.begin(), s2.end(), s1.begin());
    if (res.first== s2.end()) {
        return true;
    }

    res = std::mismatch(res.first, s2.end(), ++res.second);
    if (res.first== s2.end()) {
        return true;
    }
    return false;
}
Spelling fixes
Source Link
Toby Speight
  • 81.7k
  • 14
  • 101
  • 308

Generally Interview questions check multiple things at once. You for example would have faildfailed in my view, as you wrote a generic solution, to a much simpler test.

Your algorithm would iterate over the whole string a before it would find the missmatchmismatch. Therefore, check for sizes first

  1. Equal length -> You can only replace a character so if there is a missmatchmismatch only check if there is a second one.

  2. Strings differ by 1 -> If there is a missmatchmismatch you should realize, that deletion or insertion of characters are equivalent. Consider the following

      s1 = "abc"
      s2 = "ac"
    

    It doesntdoesn't matter if you insert b into s1 or delete it from s2. The important part is that the "c" match.

Generally Interview questions check multiple things at once. You for example would have faild in my view, as you wrote a generic solution, to a much simpler test.

Your algorithm would iterate over the whole string a before it would find the missmatch. Therefore, check for sizes first

  1. Equal length -> You can only replace a character so if there is a missmatch only check if there is a second one.

  2. Strings differ by 1 -> If there is a missmatch you should realize, that deletion or insertion of characters are equivalent. Consider the following

      s1 = "abc"
      s2 = "ac"
    

    It doesnt matter if you insert b into s1 or delete it from s2. The important part is that the "c" match.

Generally Interview questions check multiple things at once. You for example would have failed in my view, as you wrote a generic solution to a much simpler test.

Your algorithm would iterate over the whole string a before it would find the mismatch. Therefore, check for sizes first

  1. Equal length -> You can only replace a character so if there is a mismatch only check if there is a second one.

  2. Strings differ by 1 -> If there is a mismatch you should realize, that deletion or insertion of characters are equivalent. Consider the following

      s1 = "abc"
      s2 = "ac"
    

    It doesn't matter if you insert b into s1 or delete it from s2. The important part is that the "c" match.

Fix error if the first missmatch is the last character in s2 and wrong increment, add final return and fix typo
Source Link
miscco
  • 4.3k
  • 11
  • 17
  1. Equal length -> You can only replace a character so if there is a missmatch only check if there is a second one.

  2. Strings differ by 1 -> If there is a missmatch you should realize, that deletion or insertion of characters are equivalent. Consider the following

      s1 = "abc"
      s2 = "ac"
    

    It odesntdoesnt matter if you insert b into s1 or delete it from s2. The important part is that the "c" match.

bool oneAway(const string& s1, const string& s2)
{
    if ((s2.size() > s1.size()) {
       return oneAway(s2, s1);
    }
    
    // From here s1.size() >= s2.size()
    if ((s1.size() - s2.size() > 1) {
       return false;
    }
        
    auto it_s1 = s1.begin();
    auto it_s2 = s2.begin();
    bool missmatchFound = false;
    for (; it_s2 != s2.end(); ++it_s1, ++it_s2) {
        if (*it_s1 != *it_s2) {
            if (missmatchFound) {
                return false;
            }
            if (it_s2 == s2.end()) {
                return true;s1.size() == s2.size();
            }
            missmatchFound = true;
            // If both have same size simply search for the second missmatch, so nothing to do
            if (s1.size() != s2.size()) {
                // "insert" the missing character or equally
                // "remove" the wrong character
                if (*it_s2 == *std::next(it_s1, 1)) {
                    ++it_s2;++it_s1;
                } else {
                    return false;   
                }
            }
        }
    }
    return true;
}
  1. Equal length -> You can only replace a character so if there is a missmatch only check if there is a second one.

  2. Strings differ by 1 -> If there is a missmatch you should realize, that deletion or insertion of characters are equivalent. Consider the following

      s1 = "abc"
      s2 = "ac"
    

    It odesnt matter if you insert b into s1 or delete it from s2. The important part is that the "c" match.

bool oneAway(const string& s1, const string& s2)
{
    if ((s2.size() > s1.size()) {
       return oneAway(s2, s1);
    }
    
    // From here s1.size() >= s2.size()
    if ((s1.size() - s2.size() > 1) {
       return false;
    }
        
    auto it_s1 = s1.begin();
    auto it_s2 = s2.begin();
    bool missmatchFound = false;
    for (; it_s2 != s2.end(); ++it_s1, ++it_s2) {
        if (*it_s1 != *it_s2) {
            if (missmatchFound) {
                return false;
            }
            if (it_s2 == s2.end()) {
                return true;
            }
            missmatchFound = true;
            // If both have same size simply search for the second missmatch, so nothing to do
            if (s1.size() != s2.size()) {
                // "insert" the missing character or equally
                // "remove" the wrong character
                if (*it_s2 == *std::next(it_s1, 1)) {
                    ++it_s2;
                } else {
                    return false;   
                }
            }
        }
    }
}
  1. Equal length -> You can only replace a character so if there is a missmatch only check if there is a second one.

  2. Strings differ by 1 -> If there is a missmatch you should realize, that deletion or insertion of characters are equivalent. Consider the following

      s1 = "abc"
      s2 = "ac"
    

    It doesnt matter if you insert b into s1 or delete it from s2. The important part is that the "c" match.

bool oneAway(const string& s1, const string& s2)
{
    if ((s2.size() > s1.size()) {
       return oneAway(s2, s1);
    }
    
    // From here s1.size() >= s2.size()
    if ((s1.size() - s2.size() > 1) {
       return false;
    }
        
    auto it_s1 = s1.begin();
    auto it_s2 = s2.begin();
    bool missmatchFound = false;
    for (; it_s2 != s2.end(); ++it_s1, ++it_s2) {
        if (*it_s1 != *it_s2) {
            if (missmatchFound) {
                return false;
            }
            if (it_s2 == s2.end()) {
                return s1.size() == s2.size();
            }
            missmatchFound = true;
            // If both have same size simply search for the second missmatch, so nothing to do
            if (s1.size() != s2.size()) {
                // "insert" the missing character or equally
                // "remove" the wrong character
                if (*it_s2 == *std::next(it_s1, 1)) {
                    ++it_s1;
                } else {
                    return false;   
                }
            }
        }
    }
    return true;
}
Source Link
miscco
  • 4.3k
  • 11
  • 17
Loading