Checking for palindromes - list-comprehension

def palindrome(s):
for i in range(0,len(s)-1):
if s[i] == s[i][::-1]:
return s[i]
words = ['foof','boom','aanaa','nana']
print(palindrome(words))
am trying to make it check for palindromes in a huge text, though, beside the point, I only found one palindrome with my function. I decided to test it with something trivial, but it only regards 'foof' as a palindrome. There is something fundamentally wrong with the for loop, my guess, but I cannot, for the world of me, figure out what the problem is.
A side question: my first post I wrote the code and used the Code Sample button to make it format as a code, somewhat, but somebody had to edit my post so there would be these syntax colours in the code. How can I do it myself, so there would be no need for someone else to edit my posts? :)
Cheers

It's because of your return statement, the function will stop executing as soon as it finds the first palindrome.
You need to create a new list inside your function and each palindrome to that.
def palindrome(s):
l = []
for i in range(0,len(s)-1):
if s[i] == s[i][::-1]:
l.append(s[i])
return l
The function should return a list of palindromes and not just the first one...

Related

Palindrome coding and logic

When investigating if a string is Palindrome, cant i just take the reverse of the reversed string? whats wrong with my code?
def reverse(s):
return s[::-1]
def isPalindrome(s):
if (s == reverse(reverse(s))):
return True
else:
return False
reverse(reverse(s)) always equals s. You want to check whether s equals reverse(s):
def is_palindrome(s):
return s == reverse(s)
It depends on what you are aiming to do. If you just want to have the logic implemented, then your version would work (yet you still have to correct your bug there, it's if (s == reverse(s)) and not reversing the reversed version); however, if that's the task which was given to you in your coding interview, then you're not really doing it right, because of:
You're using an integral API call to reverse the string (and hence you're not implementing isPalindrome);
The time complexity of your version will be much worse than the
complexity of isPalindrome algorithm per se.

I am not sure how to fix the "TypeError: sequence item 1: expected str instance, int found" in my code?

I am having trouble with the second function in converting it back to the original string. I see what the issue is as when I call previous function, the tuple has a string and an int. So I assume I must convert that int to a string. But based on the code I wrote, I am not sure where to convert it. Hopefully, I am on the right track with this. My professor is very strict when it comes to certain things I cannot use any built-ins. Thank you. Any help is appreciated.
EDIT
Will put code back soon
My suggestion is in this case to use print statements for debugging.
def rldecode(rlencode):
decodedString = ""
L = []
for i in rlencode:
counter = 0
occurrence = i[1] # tuple (item, occurrence) == positions (0, 1)
for j in range(occurrence):
L.append(i[0])
return ''.join(L)

Why is the time complexity of this algorithm exponential?

During an interview, I was asked the time complexity of the following algorithm:
static bool SetContainsString(string searchString, HashSet<string> setOfStrings)
{
for (int i = 0; i < searchString.Length; i++)
{
var segment = searchString.Substring(0, i + 1);
if (setOfStrings.Contains(segment))
{
var remainingSegment = searchString.Substring(segment.Length);
if (remainingSegment == "") return true;
return SetContainsString(remainingSegment, setOfStrings);
}
}
return false;
}
I answered "linear" because it appears to me to loop only through the length of searchString. Yes, it is recursive, but the recursive call is only on the portion of the string that has not yet been iterated over, so the end result number of iterations is the length of the string.
I was told by my interviewer that the time complexity in the worst case is exponential.
Can anyone help me clarify this? If I am wrong, I need to understand why.
I believe that your interviewer was incorrect here. Here’s how I’d argue why the time complexity isn’t exponential:
Each call to the function either makes zero or one recursive call.
Each recursive call reduces the length of the string by at least one.
This bounds the total number of recursive calls at O(n), where n is the length of the input string. Each individual recursive call does a polynomial amount of work, so the total work done is some polynomial.
I think the reason your interviewer was confused here is that the code given above - which I think is supposed to check if a string can be decomposed into one or more words - doesn’t work correctly in all cases. In particular, notice that the recursion works by always optimistically grabbing the first prefix it finds that’s a word and assuming that what it grabbed is the right way to split the word apart. But imagine you have a word like “applesauce.” If you pull off “a” and try to recursively form “pplesauce,” you’ll incorrectly report that the word isn’t a compound because theres no way to decompose “pplesauce.” To fix this, you’d need to change the recursive call to something like this:
if (SetContainsString(...)) return true;
This way, if you pick the wrong split, you’ll go on to check the other possible splits you can make. That variant on the code does take exponential time in the worst case because it can potentially revisit the same substrings multiple times, and I think that’s what the interviewer incorrectly thought you were doing.

Is this recursive?

Second attempt here, I just wanted to know if this is considered a recursive function.
The purpose of the function is to take a string and
if the the first element is equal to the last element
then append the last element to a list and return nothing,
else call istelf and pass the same string from index [1]
finally append the first element to the list
I know that error checking needs to be done on the if statement. However I am only doing this to try and get my head around recursion...Struggling to be honest.
Also I would never write a program like this if it where anything but trivial I just wanted to check if my understanding is correct so far.
def parse(theList):
theList.reverse()
parsedString = ''.join(theList)
return parsedString
def recursiveMessage(theString):
lastElement = theString[len(theString) - 1]
if theString[0] == lastElement:
buildString.append(theString[0])
return None
else:
recursiveMessage(theString[1::])
buildString.append(theString[0])
toPrint = "Hello Everyone!"
buildString = []
recursiveMessage(toPrint)
print(parse(buildString))
Thanks again.
Is this recursive?
If at any point in a function's execution it calls itself, then it is consider recursive. This happens in your example, so recursiveMessage is indeed recursive.
so which is quicker recursion or iteration?
Recursion is usually much slower and consumes more space due to a new stack frame having to be created on the call stack each recursive call. If you know your recursive function will need to be run many times, iteration is the best route.
As an interesting side note, many compilers actually optimize a recursive function by rolling it out into a loop anyways.

Doesn't accept the list index?

I have this peice of code:
n = int (input ('Enter the Number of Players: '))
m = [[j] for j in range (0, n)]
all_names= []
i = 0
while n > 1:
m[i] = input('Player {0}: '.format (i+1))
all_names.extend ([m[i]])
if m[i][0] != m[i-1][-1]:
b= m.pop (i)
n = n-1
if all_names.count (m[i]) == 2:
n = n-1
b= m.pop (i)
i = i+1
It says the index is out of range (second if clause)
but I dont get it, why?
I hate to not answer your question directly, but what you're trying to do seems... really confusing. Python has a sort of rule that there's supposed to be a really clear, clean way of doing things, so if a piece of code looks really funky (especially for such a simple function), it's probably not using the right approach.
If you just want to create a container of names, there are numerous simpler ways of doing it:
players=int(input("How many players?\n"))
player_names=set()
while len(player_names)<players:
player_names.add(input("What is player {}'s name?\n".format(len(player_names)+1)))
... will give you a set of unique player names, although this won't be ordered. That might matter (your implementation kept order, so maybe it is), and in this case you could still use a list and add a small check to make sure you were adding a new name and not repeatedly adding names:
players=int(input("How many players?\n"))
player_names=list()
while len(player_names)<players:
playname=input("What is player {}'s name?\n".format(len(player_names)+1))
if playname not in player_names:
player_names.append(playname)
I'm open to someone haranguing me about dodging the question, particularly if there's a purpose/reason for the approach the questioner took.
Length of m decreases every time the code enters the first if clause. However, you increment the value of i in each iteration. So, at the midpoint of length of m (if the 1st clause is entered always) or a little later, the value of i will be bigger than the value of m and you will get an index out of range.

Resources