Check if two strings are one 'edit' apart using Python
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
add a comment |
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
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
add a comment |
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
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
python strings python-3.x complexity edit-distance
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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:]
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
|
show 6 more comments
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.
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, abbreviatenum_different_charstonum_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 itis_one_waybut it's actuallyis_one_Away. Hope that makes sense now.
– Mathias Ettinger
Sep 17 '16 at 19:09
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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:]
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
|
show 6 more comments
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:]
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
|
show 6 more comments
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:]
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:]
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
|
show 6 more comments
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
|
show 6 more comments
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.
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, abbreviatenum_different_charstonum_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 itis_one_waybut it's actuallyis_one_Away. Hope that makes sense now.
– Mathias Ettinger
Sep 17 '16 at 19:09
add a comment |
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.
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, abbreviatenum_different_charstonum_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 itis_one_waybut it's actuallyis_one_Away. Hope that makes sense now.
– Mathias Ettinger
Sep 17 '16 at 19:09
add a comment |
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.
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.
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, abbreviatenum_different_charstonum_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 itis_one_waybut it's actuallyis_one_Away. Hope that makes sense now.
– Mathias Ettinger
Sep 17 '16 at 19:09
add a comment |
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, abbreviatenum_different_charstonum_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 itis_one_waybut it's actuallyis_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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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