Check if two strings are one 'edit' apart using Python












4















The code below is my solution in python 3 to exercise 1.5 in Cracking the Coding Interview. I would appreciate feedback on both the algorithm (improvements to space and time complexity) and/or coding style. I think the time and space complexity of the code below is $O(n^{2})$ and $O(n)$ respectively.



The exercise statement is as follows:




Given 2 Strings write a function to check if they are 1 edit away. There are three type of edits



1) Insert a character



2) Remove a character



3) Replace a character




I wrote the code in Python 3.5 and confirmed that it passed a small unit test. For this problem I am particularly interested in feedback on where in my code (if at all) I should include more comments.



import unittest

def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""
if len(first) < len(other):
first, other = other, first

if len(first) - len(other) > 1:
return False

elif len(first) - len(other) == 1:
for pos in range(len(first)):
if first[:pos] + first[pos+1:] == other:
return True
return False

else:
num_different_chars = sum(1 for pos in range(len(first)) if first[pos] != other[pos])
return num_different_chars < 2


class MyTest(unittest.TestCase):
def test_is_one_away(self):
self.assertEqual(is_one_away('pale', 'ale'), True)
self.assertEqual(is_one_away('pales', 'pale'), True)
self.assertEqual(is_one_away('pale', 'bale'), True)
self.assertEqual(is_one_away('pale', 'bake'), False)
self.assertEqual(is_one_away('ale', 'pale'), True)
self.assertEqual(is_one_away('aale', 'ale'), True)
self.assertEqual(is_one_away('aael', 'ale'), False)
self.assertEqual(is_one_away('motherinlaw', 'womanhitler'), False)
self.assertEqual(is_one_away('motherinlaw','motherinlow'), True)









share|improve this question

























  • Is it an implementation of Levenshtein distance?

    – Laurent LAPORTE
    Sep 17 '16 at 12:25






  • 2





    You will probably be interested in how Peter Norvig solved a problem similar to this (a spelling corrector): norvig.com/spell-correct.html

    – Caridorc
    Sep 17 '16 at 12:45
















4















The code below is my solution in python 3 to exercise 1.5 in Cracking the Coding Interview. I would appreciate feedback on both the algorithm (improvements to space and time complexity) and/or coding style. I think the time and space complexity of the code below is $O(n^{2})$ and $O(n)$ respectively.



The exercise statement is as follows:




Given 2 Strings write a function to check if they are 1 edit away. There are three type of edits



1) Insert a character



2) Remove a character



3) Replace a character




I wrote the code in Python 3.5 and confirmed that it passed a small unit test. For this problem I am particularly interested in feedback on where in my code (if at all) I should include more comments.



import unittest

def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""
if len(first) < len(other):
first, other = other, first

if len(first) - len(other) > 1:
return False

elif len(first) - len(other) == 1:
for pos in range(len(first)):
if first[:pos] + first[pos+1:] == other:
return True
return False

else:
num_different_chars = sum(1 for pos in range(len(first)) if first[pos] != other[pos])
return num_different_chars < 2


class MyTest(unittest.TestCase):
def test_is_one_away(self):
self.assertEqual(is_one_away('pale', 'ale'), True)
self.assertEqual(is_one_away('pales', 'pale'), True)
self.assertEqual(is_one_away('pale', 'bale'), True)
self.assertEqual(is_one_away('pale', 'bake'), False)
self.assertEqual(is_one_away('ale', 'pale'), True)
self.assertEqual(is_one_away('aale', 'ale'), True)
self.assertEqual(is_one_away('aael', 'ale'), False)
self.assertEqual(is_one_away('motherinlaw', 'womanhitler'), False)
self.assertEqual(is_one_away('motherinlaw','motherinlow'), True)









share|improve this question

























  • Is it an implementation of Levenshtein distance?

    – Laurent LAPORTE
    Sep 17 '16 at 12:25






  • 2





    You will probably be interested in how Peter Norvig solved a problem similar to this (a spelling corrector): norvig.com/spell-correct.html

    – Caridorc
    Sep 17 '16 at 12:45














4












4








4








The code below is my solution in python 3 to exercise 1.5 in Cracking the Coding Interview. I would appreciate feedback on both the algorithm (improvements to space and time complexity) and/or coding style. I think the time and space complexity of the code below is $O(n^{2})$ and $O(n)$ respectively.



The exercise statement is as follows:




Given 2 Strings write a function to check if they are 1 edit away. There are three type of edits



1) Insert a character



2) Remove a character



3) Replace a character




I wrote the code in Python 3.5 and confirmed that it passed a small unit test. For this problem I am particularly interested in feedback on where in my code (if at all) I should include more comments.



import unittest

def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""
if len(first) < len(other):
first, other = other, first

if len(first) - len(other) > 1:
return False

elif len(first) - len(other) == 1:
for pos in range(len(first)):
if first[:pos] + first[pos+1:] == other:
return True
return False

else:
num_different_chars = sum(1 for pos in range(len(first)) if first[pos] != other[pos])
return num_different_chars < 2


class MyTest(unittest.TestCase):
def test_is_one_away(self):
self.assertEqual(is_one_away('pale', 'ale'), True)
self.assertEqual(is_one_away('pales', 'pale'), True)
self.assertEqual(is_one_away('pale', 'bale'), True)
self.assertEqual(is_one_away('pale', 'bake'), False)
self.assertEqual(is_one_away('ale', 'pale'), True)
self.assertEqual(is_one_away('aale', 'ale'), True)
self.assertEqual(is_one_away('aael', 'ale'), False)
self.assertEqual(is_one_away('motherinlaw', 'womanhitler'), False)
self.assertEqual(is_one_away('motherinlaw','motherinlow'), True)









share|improve this question
















The code below is my solution in python 3 to exercise 1.5 in Cracking the Coding Interview. I would appreciate feedback on both the algorithm (improvements to space and time complexity) and/or coding style. I think the time and space complexity of the code below is $O(n^{2})$ and $O(n)$ respectively.



The exercise statement is as follows:




Given 2 Strings write a function to check if they are 1 edit away. There are three type of edits



1) Insert a character



2) Remove a character



3) Replace a character




I wrote the code in Python 3.5 and confirmed that it passed a small unit test. For this problem I am particularly interested in feedback on where in my code (if at all) I should include more comments.



import unittest

def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""
if len(first) < len(other):
first, other = other, first

if len(first) - len(other) > 1:
return False

elif len(first) - len(other) == 1:
for pos in range(len(first)):
if first[:pos] + first[pos+1:] == other:
return True
return False

else:
num_different_chars = sum(1 for pos in range(len(first)) if first[pos] != other[pos])
return num_different_chars < 2


class MyTest(unittest.TestCase):
def test_is_one_away(self):
self.assertEqual(is_one_away('pale', 'ale'), True)
self.assertEqual(is_one_away('pales', 'pale'), True)
self.assertEqual(is_one_away('pale', 'bale'), True)
self.assertEqual(is_one_away('pale', 'bake'), False)
self.assertEqual(is_one_away('ale', 'pale'), True)
self.assertEqual(is_one_away('aale', 'ale'), True)
self.assertEqual(is_one_away('aael', 'ale'), False)
self.assertEqual(is_one_away('motherinlaw', 'womanhitler'), False)
self.assertEqual(is_one_away('motherinlaw','motherinlow'), True)






python strings python-3.x complexity edit-distance






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 17 '16 at 5:12







newToProgramming

















asked Sep 17 '16 at 1:24









newToProgrammingnewToProgramming

4511018




4511018













  • Is it an implementation of Levenshtein distance?

    – Laurent LAPORTE
    Sep 17 '16 at 12:25






  • 2





    You will probably be interested in how Peter Norvig solved a problem similar to this (a spelling corrector): norvig.com/spell-correct.html

    – Caridorc
    Sep 17 '16 at 12:45



















  • Is it an implementation of Levenshtein distance?

    – Laurent LAPORTE
    Sep 17 '16 at 12:25






  • 2





    You will probably be interested in how Peter Norvig solved a problem similar to this (a spelling corrector): norvig.com/spell-correct.html

    – Caridorc
    Sep 17 '16 at 12:45

















Is it an implementation of Levenshtein distance?

– Laurent LAPORTE
Sep 17 '16 at 12:25





Is it an implementation of Levenshtein distance?

– Laurent LAPORTE
Sep 17 '16 at 12:25




2




2





You will probably be interested in how Peter Norvig solved a problem similar to this (a spelling corrector): norvig.com/spell-correct.html

– Caridorc
Sep 17 '16 at 12:45





You will probably be interested in how Peter Norvig solved a problem similar to this (a spelling corrector): norvig.com/spell-correct.html

– Caridorc
Sep 17 '16 at 12:45










2 Answers
2






active

oldest

votes


















4














All three cases are the same: you iterate over both string until there is a difference, you skip that difference and you check that the remaining of the strings are the same.



The only difference being how you skip the difference: you can store that in a dictionnary to also help short circuit in cases the length difference is 2 or more:



def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""

skip_difference = {
-1: lambda i: (i, i+1), # Delete
1: lambda i: (i+1, i), # Add
0: lambda i: (i+1, i+1), # Modify
}
try:
skip = skip_difference[len(first) - len(other)]
except KeyError:
return False # More than 2 letters of difference

for i, (l1, l2) in enumerate(zip(first, other)):
if l1 != l2:
i -= 1 # Go back to the previous couple of identical letters
break

# At this point, either there was no differences and we exhausted one word
# and `i` indicates the last common letter or we found a difference and
# got back to the last common letter. Skip that common letter and handle
# the difference properly.
remain_first, remain_other = skip(i + 1)
return first[remain_first:] == other[remain_other:]





share|improve this answer


























  • Wow, I understand this code and the algorithm. My question is what do I take alway from this answer so that I have a better chance of answering these sorts of questions on my own? Is the key understanding how my algorithm differs from yours and to practice transforming my code into what you have above?

    – newToProgramming
    Sep 17 '16 at 11:53






  • 2





    There is no universal answer. For this question, the key is understanding that each operation is nearly the same so what is important is using the same part of the code to handle parts of the algorithm that are the same. And then figuring out an efficient way to handle the part that is different.

    – Mathias Ettinger
    Sep 17 '16 at 12:02











  • Actually, I just ran this and it failed for the test first = 'pales', other = 'pale', am I missing something?

    – newToProgramming
    Sep 17 '16 at 12:46











  • I added the line if(i) == len(other) -1: return True after the for loop and it worked, not sure if that is a good way to handle that case.

    – newToProgramming
    Sep 17 '16 at 13:00






  • 1





    @newToProgramming That how slicing works, an out-of-bounds slice will return the empty element. Anyway, this version should behave according to the requirements. The thing is that we need to account for words that are identical except for an extra last letter as well as words that have a difference in the middle. So we need a way to skip the last letter of the shorter word without skipping letters that are different.

    – Mathias Ettinger
    Sep 17 '16 at 13:34



















2














You should better solve this algorithm in O(n) to pass the interview. So, in the case where you have a longer and a shorter string, skip the longest common prefix, skip one character of the longer string and compare the rest for equality.



Also, for use in real-life situations, in the case of equally long strings, you should return early as soon as there are 2 different characters.



Regarding the comments: you don't need to add any. The code is very clear in what it does, so every additional comment would disturb the reading flow.






share|improve this answer





















  • 1





    Nothing to rename. But if you want to be meticulous: rename the function "is_one_way" doesn't mean anything for me, add a newline after the docstring first.line, and optionally, abbreviate num_different_chars to num_diff_chars. Remember this: the less you have code, the less you have bugs. I'm a quibbled!

    – Laurent LAPORTE
    Sep 17 '16 at 12:18











  • @LaurentLAPORTE I, too, read it is_one_way but it's actually is_one_Away. Hope that makes sense now.

    – Mathias Ettinger
    Sep 17 '16 at 19:09











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f141603%2fcheck-if-two-strings-are-one-edit-apart-using-python%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














All three cases are the same: you iterate over both string until there is a difference, you skip that difference and you check that the remaining of the strings are the same.



The only difference being how you skip the difference: you can store that in a dictionnary to also help short circuit in cases the length difference is 2 or more:



def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""

skip_difference = {
-1: lambda i: (i, i+1), # Delete
1: lambda i: (i+1, i), # Add
0: lambda i: (i+1, i+1), # Modify
}
try:
skip = skip_difference[len(first) - len(other)]
except KeyError:
return False # More than 2 letters of difference

for i, (l1, l2) in enumerate(zip(first, other)):
if l1 != l2:
i -= 1 # Go back to the previous couple of identical letters
break

# At this point, either there was no differences and we exhausted one word
# and `i` indicates the last common letter or we found a difference and
# got back to the last common letter. Skip that common letter and handle
# the difference properly.
remain_first, remain_other = skip(i + 1)
return first[remain_first:] == other[remain_other:]





share|improve this answer


























  • Wow, I understand this code and the algorithm. My question is what do I take alway from this answer so that I have a better chance of answering these sorts of questions on my own? Is the key understanding how my algorithm differs from yours and to practice transforming my code into what you have above?

    – newToProgramming
    Sep 17 '16 at 11:53






  • 2





    There is no universal answer. For this question, the key is understanding that each operation is nearly the same so what is important is using the same part of the code to handle parts of the algorithm that are the same. And then figuring out an efficient way to handle the part that is different.

    – Mathias Ettinger
    Sep 17 '16 at 12:02











  • Actually, I just ran this and it failed for the test first = 'pales', other = 'pale', am I missing something?

    – newToProgramming
    Sep 17 '16 at 12:46











  • I added the line if(i) == len(other) -1: return True after the for loop and it worked, not sure if that is a good way to handle that case.

    – newToProgramming
    Sep 17 '16 at 13:00






  • 1





    @newToProgramming That how slicing works, an out-of-bounds slice will return the empty element. Anyway, this version should behave according to the requirements. The thing is that we need to account for words that are identical except for an extra last letter as well as words that have a difference in the middle. So we need a way to skip the last letter of the shorter word without skipping letters that are different.

    – Mathias Ettinger
    Sep 17 '16 at 13:34
















4














All three cases are the same: you iterate over both string until there is a difference, you skip that difference and you check that the remaining of the strings are the same.



The only difference being how you skip the difference: you can store that in a dictionnary to also help short circuit in cases the length difference is 2 or more:



def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""

skip_difference = {
-1: lambda i: (i, i+1), # Delete
1: lambda i: (i+1, i), # Add
0: lambda i: (i+1, i+1), # Modify
}
try:
skip = skip_difference[len(first) - len(other)]
except KeyError:
return False # More than 2 letters of difference

for i, (l1, l2) in enumerate(zip(first, other)):
if l1 != l2:
i -= 1 # Go back to the previous couple of identical letters
break

# At this point, either there was no differences and we exhausted one word
# and `i` indicates the last common letter or we found a difference and
# got back to the last common letter. Skip that common letter and handle
# the difference properly.
remain_first, remain_other = skip(i + 1)
return first[remain_first:] == other[remain_other:]





share|improve this answer


























  • Wow, I understand this code and the algorithm. My question is what do I take alway from this answer so that I have a better chance of answering these sorts of questions on my own? Is the key understanding how my algorithm differs from yours and to practice transforming my code into what you have above?

    – newToProgramming
    Sep 17 '16 at 11:53






  • 2





    There is no universal answer. For this question, the key is understanding that each operation is nearly the same so what is important is using the same part of the code to handle parts of the algorithm that are the same. And then figuring out an efficient way to handle the part that is different.

    – Mathias Ettinger
    Sep 17 '16 at 12:02











  • Actually, I just ran this and it failed for the test first = 'pales', other = 'pale', am I missing something?

    – newToProgramming
    Sep 17 '16 at 12:46











  • I added the line if(i) == len(other) -1: return True after the for loop and it worked, not sure if that is a good way to handle that case.

    – newToProgramming
    Sep 17 '16 at 13:00






  • 1





    @newToProgramming That how slicing works, an out-of-bounds slice will return the empty element. Anyway, this version should behave according to the requirements. The thing is that we need to account for words that are identical except for an extra last letter as well as words that have a difference in the middle. So we need a way to skip the last letter of the shorter word without skipping letters that are different.

    – Mathias Ettinger
    Sep 17 '16 at 13:34














4












4








4







All three cases are the same: you iterate over both string until there is a difference, you skip that difference and you check that the remaining of the strings are the same.



The only difference being how you skip the difference: you can store that in a dictionnary to also help short circuit in cases the length difference is 2 or more:



def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""

skip_difference = {
-1: lambda i: (i, i+1), # Delete
1: lambda i: (i+1, i), # Add
0: lambda i: (i+1, i+1), # Modify
}
try:
skip = skip_difference[len(first) - len(other)]
except KeyError:
return False # More than 2 letters of difference

for i, (l1, l2) in enumerate(zip(first, other)):
if l1 != l2:
i -= 1 # Go back to the previous couple of identical letters
break

# At this point, either there was no differences and we exhausted one word
# and `i` indicates the last common letter or we found a difference and
# got back to the last common letter. Skip that common letter and handle
# the difference properly.
remain_first, remain_other = skip(i + 1)
return first[remain_first:] == other[remain_other:]





share|improve this answer















All three cases are the same: you iterate over both string until there is a difference, you skip that difference and you check that the remaining of the strings are the same.



The only difference being how you skip the difference: you can store that in a dictionnary to also help short circuit in cases the length difference is 2 or more:



def is_one_away(first: str, other: str) -> bool:
"""Given two strings, check if they are one edit away. An edit can be any one of the following.
1) Inserting a character
2) Removing a character
3) Replacing a character"""

skip_difference = {
-1: lambda i: (i, i+1), # Delete
1: lambda i: (i+1, i), # Add
0: lambda i: (i+1, i+1), # Modify
}
try:
skip = skip_difference[len(first) - len(other)]
except KeyError:
return False # More than 2 letters of difference

for i, (l1, l2) in enumerate(zip(first, other)):
if l1 != l2:
i -= 1 # Go back to the previous couple of identical letters
break

# At this point, either there was no differences and we exhausted one word
# and `i` indicates the last common letter or we found a difference and
# got back to the last common letter. Skip that common letter and handle
# the difference properly.
remain_first, remain_other = skip(i + 1)
return first[remain_first:] == other[remain_other:]






share|improve this answer














share|improve this answer



share|improve this answer








edited Sep 20 '16 at 5:57

























answered Sep 17 '16 at 11:32









Mathias EttingerMathias Ettinger

23.9k33182




23.9k33182













  • Wow, I understand this code and the algorithm. My question is what do I take alway from this answer so that I have a better chance of answering these sorts of questions on my own? Is the key understanding how my algorithm differs from yours and to practice transforming my code into what you have above?

    – newToProgramming
    Sep 17 '16 at 11:53






  • 2





    There is no universal answer. For this question, the key is understanding that each operation is nearly the same so what is important is using the same part of the code to handle parts of the algorithm that are the same. And then figuring out an efficient way to handle the part that is different.

    – Mathias Ettinger
    Sep 17 '16 at 12:02











  • Actually, I just ran this and it failed for the test first = 'pales', other = 'pale', am I missing something?

    – newToProgramming
    Sep 17 '16 at 12:46











  • I added the line if(i) == len(other) -1: return True after the for loop and it worked, not sure if that is a good way to handle that case.

    – newToProgramming
    Sep 17 '16 at 13:00






  • 1





    @newToProgramming That how slicing works, an out-of-bounds slice will return the empty element. Anyway, this version should behave according to the requirements. The thing is that we need to account for words that are identical except for an extra last letter as well as words that have a difference in the middle. So we need a way to skip the last letter of the shorter word without skipping letters that are different.

    – Mathias Ettinger
    Sep 17 '16 at 13:34



















  • Wow, I understand this code and the algorithm. My question is what do I take alway from this answer so that I have a better chance of answering these sorts of questions on my own? Is the key understanding how my algorithm differs from yours and to practice transforming my code into what you have above?

    – newToProgramming
    Sep 17 '16 at 11:53






  • 2





    There is no universal answer. For this question, the key is understanding that each operation is nearly the same so what is important is using the same part of the code to handle parts of the algorithm that are the same. And then figuring out an efficient way to handle the part that is different.

    – Mathias Ettinger
    Sep 17 '16 at 12:02











  • Actually, I just ran this and it failed for the test first = 'pales', other = 'pale', am I missing something?

    – newToProgramming
    Sep 17 '16 at 12:46











  • I added the line if(i) == len(other) -1: return True after the for loop and it worked, not sure if that is a good way to handle that case.

    – newToProgramming
    Sep 17 '16 at 13:00






  • 1





    @newToProgramming That how slicing works, an out-of-bounds slice will return the empty element. Anyway, this version should behave according to the requirements. The thing is that we need to account for words that are identical except for an extra last letter as well as words that have a difference in the middle. So we need a way to skip the last letter of the shorter word without skipping letters that are different.

    – Mathias Ettinger
    Sep 17 '16 at 13:34

















Wow, I understand this code and the algorithm. My question is what do I take alway from this answer so that I have a better chance of answering these sorts of questions on my own? Is the key understanding how my algorithm differs from yours and to practice transforming my code into what you have above?

– newToProgramming
Sep 17 '16 at 11:53





Wow, I understand this code and the algorithm. My question is what do I take alway from this answer so that I have a better chance of answering these sorts of questions on my own? Is the key understanding how my algorithm differs from yours and to practice transforming my code into what you have above?

– newToProgramming
Sep 17 '16 at 11:53




2




2





There is no universal answer. For this question, the key is understanding that each operation is nearly the same so what is important is using the same part of the code to handle parts of the algorithm that are the same. And then figuring out an efficient way to handle the part that is different.

– Mathias Ettinger
Sep 17 '16 at 12:02





There is no universal answer. For this question, the key is understanding that each operation is nearly the same so what is important is using the same part of the code to handle parts of the algorithm that are the same. And then figuring out an efficient way to handle the part that is different.

– Mathias Ettinger
Sep 17 '16 at 12:02













Actually, I just ran this and it failed for the test first = 'pales', other = 'pale', am I missing something?

– newToProgramming
Sep 17 '16 at 12:46





Actually, I just ran this and it failed for the test first = 'pales', other = 'pale', am I missing something?

– newToProgramming
Sep 17 '16 at 12:46













I added the line if(i) == len(other) -1: return True after the for loop and it worked, not sure if that is a good way to handle that case.

– newToProgramming
Sep 17 '16 at 13:00





I added the line if(i) == len(other) -1: return True after the for loop and it worked, not sure if that is a good way to handle that case.

– newToProgramming
Sep 17 '16 at 13:00




1




1





@newToProgramming That how slicing works, an out-of-bounds slice will return the empty element. Anyway, this version should behave according to the requirements. The thing is that we need to account for words that are identical except for an extra last letter as well as words that have a difference in the middle. So we need a way to skip the last letter of the shorter word without skipping letters that are different.

– Mathias Ettinger
Sep 17 '16 at 13:34





@newToProgramming That how slicing works, an out-of-bounds slice will return the empty element. Anyway, this version should behave according to the requirements. The thing is that we need to account for words that are identical except for an extra last letter as well as words that have a difference in the middle. So we need a way to skip the last letter of the shorter word without skipping letters that are different.

– Mathias Ettinger
Sep 17 '16 at 13:34













2














You should better solve this algorithm in O(n) to pass the interview. So, in the case where you have a longer and a shorter string, skip the longest common prefix, skip one character of the longer string and compare the rest for equality.



Also, for use in real-life situations, in the case of equally long strings, you should return early as soon as there are 2 different characters.



Regarding the comments: you don't need to add any. The code is very clear in what it does, so every additional comment would disturb the reading flow.






share|improve this answer





















  • 1





    Nothing to rename. But if you want to be meticulous: rename the function "is_one_way" doesn't mean anything for me, add a newline after the docstring first.line, and optionally, abbreviate num_different_chars to num_diff_chars. Remember this: the less you have code, the less you have bugs. I'm a quibbled!

    – Laurent LAPORTE
    Sep 17 '16 at 12:18











  • @LaurentLAPORTE I, too, read it is_one_way but it's actually is_one_Away. Hope that makes sense now.

    – Mathias Ettinger
    Sep 17 '16 at 19:09
















2














You should better solve this algorithm in O(n) to pass the interview. So, in the case where you have a longer and a shorter string, skip the longest common prefix, skip one character of the longer string and compare the rest for equality.



Also, for use in real-life situations, in the case of equally long strings, you should return early as soon as there are 2 different characters.



Regarding the comments: you don't need to add any. The code is very clear in what it does, so every additional comment would disturb the reading flow.






share|improve this answer





















  • 1





    Nothing to rename. But if you want to be meticulous: rename the function "is_one_way" doesn't mean anything for me, add a newline after the docstring first.line, and optionally, abbreviate num_different_chars to num_diff_chars. Remember this: the less you have code, the less you have bugs. I'm a quibbled!

    – Laurent LAPORTE
    Sep 17 '16 at 12:18











  • @LaurentLAPORTE I, too, read it is_one_way but it's actually is_one_Away. Hope that makes sense now.

    – Mathias Ettinger
    Sep 17 '16 at 19:09














2












2








2







You should better solve this algorithm in O(n) to pass the interview. So, in the case where you have a longer and a shorter string, skip the longest common prefix, skip one character of the longer string and compare the rest for equality.



Also, for use in real-life situations, in the case of equally long strings, you should return early as soon as there are 2 different characters.



Regarding the comments: you don't need to add any. The code is very clear in what it does, so every additional comment would disturb the reading flow.






share|improve this answer















You should better solve this algorithm in O(n) to pass the interview. So, in the case where you have a longer and a shorter string, skip the longest common prefix, skip one character of the longer string and compare the rest for equality.



Also, for use in real-life situations, in the case of equally long strings, you should return early as soon as there are 2 different characters.



Regarding the comments: you don't need to add any. The code is very clear in what it does, so every additional comment would disturb the reading flow.







share|improve this answer














share|improve this answer



share|improve this answer








edited Sep 17 '16 at 8:00

























answered Sep 17 '16 at 7:54









Roland IlligRoland Illig

10.8k11844




10.8k11844








  • 1





    Nothing to rename. But if you want to be meticulous: rename the function "is_one_way" doesn't mean anything for me, add a newline after the docstring first.line, and optionally, abbreviate num_different_chars to num_diff_chars. Remember this: the less you have code, the less you have bugs. I'm a quibbled!

    – Laurent LAPORTE
    Sep 17 '16 at 12:18











  • @LaurentLAPORTE I, too, read it is_one_way but it's actually is_one_Away. Hope that makes sense now.

    – Mathias Ettinger
    Sep 17 '16 at 19:09














  • 1





    Nothing to rename. But if you want to be meticulous: rename the function "is_one_way" doesn't mean anything for me, add a newline after the docstring first.line, and optionally, abbreviate num_different_chars to num_diff_chars. Remember this: the less you have code, the less you have bugs. I'm a quibbled!

    – Laurent LAPORTE
    Sep 17 '16 at 12:18











  • @LaurentLAPORTE I, too, read it is_one_way but it's actually is_one_Away. Hope that makes sense now.

    – Mathias Ettinger
    Sep 17 '16 at 19:09








1




1





Nothing to rename. But if you want to be meticulous: rename the function "is_one_way" doesn't mean anything for me, add a newline after the docstring first.line, and optionally, abbreviate num_different_chars to num_diff_chars. Remember this: the less you have code, the less you have bugs. I'm a quibbled!

– Laurent LAPORTE
Sep 17 '16 at 12:18





Nothing to rename. But if you want to be meticulous: rename the function "is_one_way" doesn't mean anything for me, add a newline after the docstring first.line, and optionally, abbreviate num_different_chars to num_diff_chars. Remember this: the less you have code, the less you have bugs. I'm a quibbled!

– Laurent LAPORTE
Sep 17 '16 at 12:18













@LaurentLAPORTE I, too, read it is_one_way but it's actually is_one_Away. Hope that makes sense now.

– Mathias Ettinger
Sep 17 '16 at 19:09





@LaurentLAPORTE I, too, read it is_one_way but it's actually is_one_Away. Hope that makes sense now.

– Mathias Ettinger
Sep 17 '16 at 19:09


















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f141603%2fcheck-if-two-strings-are-one-edit-apart-using-python%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to make a Squid Proxy server?

第一次世界大戦

Touch on Surface Book