couldn't figure out the string count behaviour in certain input - python

string = input("Enter the string: ")
sub_string = input("Enter sub string: ")
count = 0
idx = 0
while string.count(sub_string, idx) != 0:
count += string.count(sub_string, idx)
idx = string.index(sub_string, idx)
idx += 1
if string.count(sub_string, idx) == 0:
print(count)
break
when i give this code input as follows:
ininini
ini
It prints output 4. I tried running debugger and found out that it is incrementing count with +2 in the first step instead of +1 and I couldn't figure out that. Any suggestions would be very much helpful.

Use:
count += 1
instead of
count += string.count(sub_string, idx)
string.count(sub_string, idx) is 2 initially, and that's why you end up adding 2 in first iteration (instead of intended 1), thereby getting a 1 more than expected.
What you need is to increment count by 1 in every iteration and if you make this change, you get 3 as output.

I would use a for loop instead:
string = input("Enter the string: ")
sub_string = input("Enter sub string: ")
count = 0
for index in range(len(string) - len(sub_string) + 1):
if string[index: index + len(sub_string)] == sub_string:
count += 1
print(count)

If you are tyring to reach to get the length of the string, just use
len(string)

Related

Counting the most amount of zeros in a row in a number | Python

I want to create a function that asks for a number and then sees the most amount of zeros in a row and returns its value (ex: 5400687000360045 -> 3 | 03500400004605605600 -> 4).
So far this is all I got but it isn't working:
def zeros():
num = input('Write a number: ')
row = 0
result = 0
for i in num:
if i == '0':
while i == '0':
row += 1
if row > result:
result = row
return result
What's wrong?
EDIT:
This is what the desired output should be:
zeros()
Write a number: 03500400004605605600
4
My current output is nothing, meaning it's not returning anything
This should do it.
def zeros():
num = input('Write a number: ')
row = 0
count = 0
for i in num:
if i == '0':
count += 1
else:
row = max(row, count)
count = 0
row = max(row, count)
return row
Your code is getting stuck in an infinite loop in inner while
To do it your way, you just need to keep track of whether the number is a 0 or not (i.e. to know if it is a row of zeros or if you need to restart the count). Something like this would work:
def zeros():
num = input('Write a number: ')
row = 0
result = 0
for i in num:
if i != '0':
row = 0
else:
row += 1
if row > result:
result = row
return result
Output is as you would expect.
If you know regex, you could achieve this with much less code using:
import re
def zeros():
num = input('Write a number: ')
result = max(map(len, re.findall(r'0+', num)))
return result
Is this helpful to you..? regex (Regular expression operations) is a very handy tool which could make your life easier. Please have look at Regular expression operations
import re
def zeros():
num = input('Write a number: ')
return max(re.findall("(0+0)*", (num)))
output : 000
def zeros():
num = input('Write a number: ')
return len(max(re.findall("(0+0)*", (num))))
output : 3
I think this might work
num = input()
countOfZeros = 0
for i in range(len(num)-1):
curr = 0
if num[i] == num[i+1]:
curr = 0
if curr > countOfZeros:
countOfZeros = curr
else:
countOfZeros += 1
print(countOfZeros - 1 )

Starting Index of the Most Frequent Consecutive Number Algorithm

1) The purpose of the code: I have coded an algorithm, which is supposed to give me the exact number, which is the most frequent and consecutive at the same time number.
2) What I have tried: I have tried to write the whole code, and actually managed to get that exact number. I have also added the frequency of that number, which is the output.
3) What I need: I am looking for the algorithm, which will identify the first starting index of those consecutive numbers. For example, if the input is 123777321, as an index number 3 is needed, the reason being 777 is the most frequent consecutive number in this input, it should find its "index", and also print it out.
The Code I have written:
def maxRepeating(str):
length = len(str)
count = 0
result = str[0]
for i in range(length):
current_count = 1
for x in range(i + 1, length):
if (str[i] != str[x]):
break
current_count += 1
if current_count > count:
count = current_count
result = str[i]
print("Longest same number sequence is of number {} by being repeated {} times in a row, with the first index starting at {}".format(result, count, i))
inputString = str(input("Please enter the string: "))
maxRepeating(inputString)
Example of an input: Please enter a string: 123777321
Example of an output: Longest same number sequence is of number 7 by being repeated 3 times in a row, with the first index starting at 3
Just add a variable to track the starting index of the best sequence.
def maxRepeating(str):
length = len(str)
count = 0
result = str[0]
start_ind = None
for i in range(length):
current_count = 1
for x in range(i + 1, length):
if (str[i] != str[x]):
break
current_count += 1
if current_count > count:
count = current_count
result = str[i]
start_ind = i
print("Longest same number sequence is of number {} by being repeated {} times in a row, with the first index starting at {}".format(result, count, start_ind))
inputString = str(input("Please enter the string: "))
maxRepeating(inputString)
From your comments, I assume you are trying to get the index at which the most frequently occurring element starts right?
Declare another variable like max_index and update it each time you update count and use that to print the index.
.....
max_index = 0
for i in range(length):
current_count = 1
for x in range(i + 1, length):
if (str[i] != str[x]):
break
current_count += 1
if current_count > count:
count = current_count
result = str[i]
max_index = i
print("Longest same number sequence is of number {} by being repeated {} times in a row, with the first index starting at {}".format(result, count, max_index))
......

Counting occurrences of a sub-string without using a built-in function

My teacher challenged me of finding a way to count the occurences of the word "bob" in any random string variable without str.count(). So I did,
a = "dfjgnsdfgnbobobeob bob"
compteurDeBob = 0
for i in range (len(a) - 1):
if a[i] == "b":
if a[i+1] == "o":
if a[i+2] == "b":
compteurDeBob += 1
print(compteurDeBob)
but I wanted to find a way to do that with a word of any length as shown below, but I have no clue on how to do that...
a = input("random string: ")
word = input("Wanted word: ")
compteurDeBob = 0
for i in range (len(a)-1):
#... i don't know...
print(compteurDeBob)
a = input("random string: ")
word = input("Wanted word: ")
count = 0
for i in range(len(a)-len(word)):
if a[i:i+len(word)] == word:
count += 1
print(count)
If you want your search to be case-insensitive, then you can use lower() function:
a = input("random string: ").lower()
word = input("Wanted word: ").lower()
count = 0
for i in range(len(a)):
if a[i:i+len(word)] == word:
count += 1
print(count)
For the user input
Hi Bob. This is bob
the first approach will output 1 and the second approach will output 2
To count all overlapping occurrences (like in your example) you could just slice the string in a loop:
a = input("random string: ")
word = input("Wanted word: ")
cnt = 0
for i in range(len(a)-len(word)+1):
if a[i:i+len(word)] == word:
cnt += 1
print(cnt)
You can use string slicing. One way to adapt your code:
a = 'dfjgnsdfgnbobobeob bob'
counter = 0
value = 'bob'
chars = len(value)
for i in range(len(a) - chars + 1):
if a[i: i + chars] == value:
counter += 1
A more succinct way of writing this is possible via sum and a generator expression:
counter = sum(a[i: i + chars] == value for i in range(len(a) - chars + 1))
This works because bool is a subclass of int in Python, i.e. True / False values are considered 1 and 0 respectively.
Note str.count won't work here, as it only counts non-overlapping matches. You could utilise str.find if built-ins are allowed.
The fastest way to calculate overlapping matches is the Knuth-Morris-Pratt algorithm [wiki] which runs in O(m+n) with m the string to match, and n the size of the string.
The algorithm first builds a lookup table that acts more or less as the description of a finite state machine (FSM). First we construct such table with:
def build_kmp_table(word):
t = [-1] * (len(word)+1)
cnd = 0
for pos in range(1, len(word)):
if word[pos] == word[cnd]:
t[pos] = t[cnd]
else:
t[pos] = cnd
cnd = t[cnd]
while cnd >= 0 and word[pos] != word[cnd]:
cnd = t[cnd]
cnd += 1
t[len(word)] = cnd
return t
Then we can count with:
def count_kmp(string, word):
n = 0
wn = len(word)
t = build_kmp_table(word)
k = 0
j = 0
while j < len(string):
if string[j] == word[k]:
k += 1
j += 1
if k >= len(word):
n += 1
k = t[k]
else:
k = t[k]
if k < 0:
k += 1
j += 1
return n
The above counts overlapping instances in linear time in the string to be searched, which was an improvements of the "slicing" approach that was earlier used, that works in O(m×n).

Python - variable not updating in loop

I am trying to solve the 'Love-Letter' mystery problem of HackerRank using Python, but I am stuck at a place where in my loop a variable is not getting updated.
s = input()
first_char = s[0]
last_char = s[-1]
ascii_first_char = ord(first_char)
ascii_last_char = ord(last_char)
count = 0
i = 1
while ascii_first_char < ascii_last_char:
count += abs((ascii_last_char-ascii_first_char))
ascii_first_char = ord(s[i])
ascii_last_char = ord(s[-i])
i += 1
print(count)
If you try to run that, you would see that alc is not changing it's value according to ord(s[i]) where I keeps incrementing. Why is that happening?
You get the first letter with s[0] and the last with s[-1]. In your loop you take the next letters with the same index i.
I don't understand your condition in the while loop. Instead of "ascii_first_char < ascii_last_char" you should test if you have looked at every element of the string. For that we have to loop len(s)/2 times. Something like:
while i < len(s) - i:
or equivalent
while 2*i < len(s):
And this conditions only work for even length. I prefer for-loops when I know how many times I will loop
current_line = input()
# if length is even, we don't care about the letter in the middle
# abcde <-- just need to look for first and last 2 values
# 5 // 2 == 2
half_length = len(current_line) // 2
changes = 0
for i in range(index):
changes += abs(
ord(current_line[i]) - ord(current_line[-(i+1)])
)
print (changes)
s1 = ['abc','abcba','abcd','cba']
for s in s1:
count = 0
i = 0
j = -1
median = len(s)/2
if median == 1:
count += abs(ord(s[0])-ord(s[-1]))
else:
while i < len(s)/2:
count += abs(ord(s[j])-ord(s[i]))
i += 1
j -= 1
print(count)

Looping and Counting w/find

So I am working diligently on some examples for my homework and came across yet another error.
The original:
word = 'banana'
count = 0
for letter in word:
if letter == 'a':
count = count + 1
print count
Ok. Looks simple.
I then used this code in a function name count and generalized it so that it accepts the string and the letter as argument.
def count1(str, letter):
count = 0
word = str
for specific_letter in word:
if specific_letter == letter:
count = count + 1
print count
This is where I'm still not sure what I'm doing wrong.
I have to rewrite this function so that instead of traversing the string, it uses the three-parameter version of find from the previous section. Which this is:
def find(word, letter, startat):
index = startat
while index <= len(word):
if word[index] == letter:
return index
index = index + 1
return -1
This is how far I got... but the program doesn't work the way I want it to.
def find(str, letter, startat):
index = startat
word = str
count = 0
while index <= len(word):
if word[index] == letter:
for specific_letter in word:
if specific_letter == letter:
count = count + 1
print count
index = index + 1
Can someone point me in the right direction. I want to understand what I'm doing instead of just given the answer. Thanks.
The point of the exercise is to use the previously defined function find as a building block to implement a new function count. So, where you're going wrong is by trying to redefine find, when you should be trying to change the implementation of count.
However, there is a wrinkle in that find as you have given has a slight error, you would need to change the <= to a < in order for it to work properly. With a <=, you could enter the body of the loop with index == len(word), which would cause IndexError: string index out of range.
So fix the find function first:
def find(word, letter, startat):
index = startat
while index < len(word):
if word[index] == letter:
return index
index = index + 1
return -1
And then re-implement count, this time using find in the body:
def count(word, letter):
result = 0
startat = 0
while startat < len(word):
next_letter_position = find(word, letter, startat)
if next_letter_position != -1:
result += 1
startat = next_letter_position + 1
else:
break
return result
if __name__ == '__main__':
print count('banana', 'a')
The idea is to use find to find you the next index of the given letter.
In your code you don't use the find function.
If you want to try something interesting and pythonic: Change the original find to yield index and remove the final return -1. Oh, and fix the <= bug:
def find(word, letter, startat):
index = startat
while index < len(word):
if word[index] == letter:
yield index
index = index + 1
print list(find('hello', 'l', 0))
Now find returns all of the results. You can use it like I did in the example or with a for position in find(...): You can also simply write count in terms of the length of the result.
(Sorry, no hints on the final function in your question because I can't tell what you're trying to do. Looks like maybe you left in too much of the original function and jumbled their purposes together?)
Here's what I came up with: This should work.
def find(word, letter, startat)
index = startat
count = 0
while index < len(word):
if word[index] == letter:
count = count + 1 ##This counts when letter matches the char in word
index = index + 1
print count
>>> find('banana', 'a', 0)
3
>>> find('banana', 'n', 0)
2
>>> find('mississippi', 's', 0)
4
>>>
Try using :
def find_count(srch_wrd, srch_char, startlookingat):
counter = 0
index = startlookingat
while index < len(srch_wrd):
if srch_wrd[index] == srch_char:
counter += 1
index += 1
return counter`
def count_letter2(f, l):
count = 0
t = 0
while t < len(f):
np = f.find(l, t)
if np != -1:
count += 1
t = np + 1
"I was wrong by doing t =t +1"
else:
break
return count
print(count_letter2("banana", "a"))
print(count_letter2("abbbb", "a"))

Categories

Resources