Longest substring - python

s = 'abcabcbb'
def longsubstring(s):
if len(s)==0:
return 0
list1 = []
empty = ''
for i in s:
if i in empty:
list1.append(len(empty))
empty = ''
continue
else:
empty+=i
return max(list1)
longsubstring(s)
The above code works fine when s = 'abcabcbb'
but it returns 1 when actually 2 for s = 'aab'. Could someone debug the code tell me where I am wrong to satisfy the condition. Thanks in advance.

Here is the modification to your code that worked
s = 'aab'
def longsubstring(s):
if len(s)==0:
return 0
list1 = []
empty = ''
for i in range(0,len(s)):
empty=''
for j in range(i,len(s)):
if s[j] in empty:
list1.append(len(empty))
empty = ''
break
else:
empty+=s[j]
list1.append(len(empty))
return max(list1)
print(longsubstring(s))

Related

finding the longest common prefix of elements inside a list

I have a sequence print(lcp(["flower","flow","flight", "dog"])) which should return fl. Currently I can get it to return flowfl.
I can locate the instances where o or w should be removed, and tried different approaches to remove them. However they seem to hit syntax issue, which I cannot seem to resolve by myself.
I would very much appreciate a little guidance to either have the tools to remedy this issue my self, or learn from a working proposed solution.
def lcp(strs):
if not isinstance(strs, list) or len(strs) == 0:
return ""
if len(strs) == 1:
return strs[0]
original = strs[0]
original_max = len(original)
result = ""
for _, word in enumerate(strs[1:],1):
current_max = len(word)
i = 0
while i < current_max and i < original_max:
copy = "".join(result)
if len(copy) and copy[i-1] not in word:
# result = result.replace(copy[i-1], "")
# result = copy[:i-1]
print(copy[i-1], copy, result.index(copy[i-1]), i, word)
if word[i] == original[i]:
result += word[i]
i += 1
return result
print(lcp(["flower","flow","flight", "dog"])) # returns flowfl should be fl
print(lcp(["dog","car"])) # works
print(lcp(["dog","racecar","car"])) # works
print(lcp([])) # works
print(lcp(["one"])) # works
I worked on an alternative which does not be solve removing inside the same loop, adding a counter at the end. However my instincts suggest it can be solved within the for and while loops without increasing code bloat.
if len(result) > 1:
counter = {char: result.count(char) for char in result}
print(counter)
I have solved this using the below approach.
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
N = len(strs)
if N == 1:
return strs[0]
len_of_small_str, small_str = self.get_min_str(strs)
ans = ""
for i in range(len_of_small_str):
ch = small_str[i]
is_qualified = True
for j in range(N):
if strs[j][i] != ch:
is_qualified = False
break
if is_qualified:
ans += ch
else:
break
return ans
def get_min_str(self, A):
min_len = len(A[0])
s = A[0]
for i in range(1, len(A)):
if len(A[i]) < min_len:
min_len = len(A[i])
s = A[i]
return min_len, s
Returns the longest prefix that the set of words have in common.
def lcp(strs):
if len(strs) == 0:
return ""
result = strs[0]
for word in strs[1:]:
for i, (l1, l2) in enumerate(zip(result, word)):
if l1 != l2:
result = result[:i]
break
else:
result = result[:i+1]
return result
Results:
>>> print(lcp(["flower","flow","flight"]))
fl
>>> print(lcp(["flower","flow","flight", "dog"]))
>>> print(lcp(["dog","car"]))
>>> print(lcp(["dog","racecar","car"]))
>>> print(lcp([]))
>>> print(lcp(["one"]))
one
>>> print(lcp(["one", "one"]))
one
You might need to rephrase your goal.
By your description you don't want the longest common prefix, but the prefix that the most words have in common with the first one.
One of your issues is that your tests only test one real case and four edgecases. Make some more real examples.
Here's my proposition: I mostly added the elif to check if we already have a difference on the first letter to then discard the entry.
It also overwrites the original to rebuild the string based on the common prefix with the next word (if there are any)
def lcp(strs):
if not isinstance(strs, list) or len(strs) == 0:
return ""
if len(strs) == 1:
return strs[0]
original = strs[0]
result = ""
for word in strs[1:]:
i = 0
while i < len(word) and i < len(original) :
if word[i] == original[i]:
result += word[i]
elif i == 0:
result = original
break
i += 1
original = result
result = ""
return original
print(lcp(["flower","flow","flight", "dog"])) # fl
print(lcp(["shift", "shill", "hunter", "shame"])) # sh
print(lcp(["dog","car"])) # dog
print(lcp(["dog","racecar","car"])) # dog
print(lcp(["dog","racecar","dodge"])) # do
print(lcp([])) # [nothing]
print(lcp(["one"])) # one

list.remove(x) x seems to be in list but not being found

So in VSCode, I'm receiving this error...
Given the input
2
21 22
We have variables saying
best_choice = '22'
a: ['21', '22']
However, a.remove(best_choice) returns an error.
I am completely confounded... please help.
I checked for this problem on stacks and found that remove() doesn't work when iterating through a list, so I changed my loop to while(True). However, I'm still receiving the same error.
Here is the code:
import sys
def best_option(a):
iterator = 0
while(len(a)>1):
previous_best_digit = 0
current_best_digit = 0
best_short_option = []
return_list = []
for item in a:
if len(item)-1 < iterator:
char_previous = item[iterator-1:iterator]
dig_previous = ord(char_previous)
previous_best_digit = dig_previous
best_short_option = item
continue
char = item[iterator:iterator+1]
dig = ord(char)
if dig > current_best_digit:
current_best_digit = dig
return_list.clear()
return_list.append(item)
elif dig == current_best_digit:
return_list.append(item)
if (current_best_digit < previous_best_digit):
return_list.clear()
return_list.append(best_short_option)
a = return_list
iterator+=1
return a
def largest_number(a):
#write your code here
res = ""
while (True):
best_choice = best_option(a)
print(best_choice)
a.remove(best_choice)
res += best_choice
if (len(a)==1):
break
res.append(a)
print(res)
return res
if __name__ == '__main__':
input = sys.stdin.read()
data = input.split()
a = data[1:]
print(largest_number(a))
It's purpose create a string with the greatest possible value from a list of strings.
your best_choice is ['22'], not '22'

Backtrack Algorithm To Check Strings form Matrix

I have list:
words = ["ALI", "SIN", "ASI", "LIR", "IRI", "INI", "KAR"]
I want to check if they form matrix such as this:
and return my solution as a list like:
solution = ["ALI", "SIN", "IRI"]
I have come up with this code:
words=["ALI", "SIN", "ASI", "LIR", "IRI", "INI", "KAR"]
solution =[]
failedsolutions = []
def Get_next_word():
while True:
for word in words:
if (word in solution) == False:
solution.append(word)
if (solution in failedsolutions) == False:
return False
else:
solution.pop(len(solution) - 1 )
return True
def Check_word_order():
checker = True
for i in range(len(solution)):
for j in range(len(words[0])):
for word in words:
if solution[i][j] == word[j]:
checker = False
else:
checker = True
if checker == False:
return checker
def main():
while True:
Get_next_word()
check = Check_word_order()
if check is False:
#Backtrack
failedsolutions.append(solution)
solution.pop(len(solution) - 1 )
# else:
# solution.append()
print(solution)
main()
I am tired and no longer be able to debug my code. Help will be appreciated.
Thank you
ps: I advice not fixing my code if there is a better way to it all.
You can use this simple recursive function which will analyze all possible groups:
import itertools
import copy
words = ["ALI", "SIN", "ASI", "LIR", "IRI", "INI", "KAR"]
def get_pairs(word_group, current_words, found):
if not current_words:
return found
new_group = list(word_group)+[current_words[0]]
if all(''.join(i) in words and ''.join(i) not in new_group for i in zip(*new_group)):
return get_pairs(word_group, current_words[1:], new_group)
return get_pairs(word_group, current_words[1:], found)
starting_pairs = [i for i in itertools.combinations(words, 2)]
final_listing = filter(lambda x:x, [get_pairs(i, copy.deepcopy(words), []) for i in starting_pairs])
Output:
[['ALI', 'SIN', 'IRI'], ['ASI', 'LIR', 'INI']]
Which yields all combinations of valid matrices.
Or, without using itertools:
def get_combos(word, new_words):
if new_words[1:]:
new_list = [(yield (word, i)) for i in new_words if i != word]
for b in get_combos(new_words[0], new_words[1:]):
yield b
starting_pairs = get_combos(words[0], words[1:])
final_listing = filter(lambda x:x, [get_pairs(i, copy.deepcopy(words), []) for i in starting_pairs])

python: taking the return of a function and using it in another function

Hi guys i got my code to work by putting everything in one function which is this
spam = ''
def enterList (names):
newList = []
while True:
names = raw_input('list a series of items and press blank when finished: ')
if names == '':
break
newList = newList + [names]
a = ''
finalText = ''
listOfStuff = []
item = 0
for i in newList:
if item < len(newList)-2:
a = (i + ', ')
listOfStuff.append(a)
item +=1
elif item == len(newList)-2:
a = (i + ' and ')
listOfStuff.append(a)
item +=1
else:
a = i
listOfStuff.append(a)
break
finalText = finalText.join(listOfStuff)
return finalText
print enterList(spam)
So the above code works as i want it to. However i was trying to do the same thing by having two separate functions, the issue that i was having was that i couldn't take the return value of one function and use it in the next function.
This is the old code
spam = ''
def enterList (names):
newList = []
while True:
names = raw_input('list a series of items and press blank when finished: ')
if names == '':
break
newList = newList + [names]
return newList
print enterList(spam)
def newFunc(Addand):
a = ''
finalText = ''
listOfStuff = []
item = 0
for i in spam:
if item < len(spam)-2:
a = (i + ', ')
listOfStuff.append(a)
item +=1
elif item == len(spam)-2:
a = (i + ' and ')
listOfStuff.append(a)
item +=1
else:
a = i
listOfStuff.append(a)
break
finalText = finalText.join(listOfStuff)
return finalText
newFunc(spam)
print newFunc (spam)
I'm not sure what I was doing wrong doing it this way.
Thanks for any help to get my head around the error with this approach.
In your first function make the return statement
return newFunc(newlist)
It's not working because the second function is never actually called.

how to produce bigrams without stop words

i wrote this function for generating bigrams from string using nltk.bigrams and ignoring stop words and letters but the stop words and letters still appear in the output. please help me to correct the funtion.
def bigramReturner (tweetString, stopWords):
bigramFeatureVector = []
tweetStringG = tweetString.lower()
tweetStringG = tweetString.split()
for i in tweetStringG:
i =replaceTwoOrMore(i)
i =i.strip('\'"?,.')
val = re.search(r"^[a-zA-Z][a-zA-Z0-9]*[a-zA-Z]+[a-zA-Z0-9]*$", i)
if(i in stopWords is None):
continue
else:
for i in nltk.bigrams(tweetStringG):
bigramFeatureVector.append(' '.join(i))
return bigramFeatureVector
Try removing the is None check as currently you're comparing True or False with None
def bigramReturner (tweetString, stopWords):
bigramFeatureVector = []
tweetStringG = tweetString.lower()
tweetStringG = tweetString.split()
for i in tweetStringG:
i =replaceTwoOrMore(i)
i =i.strip('\'"?,.')
val = re.search(r"^[a-zA-Z][a-zA-Z0-9]*[a-zA-Z]+[a-zA-Z0-9]*$", i)
if(i in stopWords):
continue
else:
for i in nltk.bigrams(tweetStringG):
bigramFeatureVector.append(' '.join(i))
return bigramFeatureVector

Categories

Resources