Check how many consecutive times appear in a string - python-3.x

I want to to display a number or an alphabet which appears mostly
consecutive in a given string or numbers or both.
Example:
s= 'aabskeeebadeeee'
output: e appears 4 consecutive times
I thought about set the string then and for each element loop the string to check if equal with element set element if so count =+1 and check if next to it is not equal add counter value to list with same index as in set, if is add counter value to li list if value is bigger than existing.
The problem is error index out or range although I think I am watching it.
s = 'aabskeeebadeeee'
c = 0
t = list(set(s)) # list of characters in s
li=[0,0,0,0,0,0] # list for counted repeats
print(t)
for x in t:
h = t.index(x)
for index, i in enumerate(s):
maximus = len(s)
if i == x:
c += 1
if index < maximus:
if s[index +1] != x: # if next element is not x
if c > li[h]: #update c if bigger than existing
li[h] = c
c = 0
else:
if c > li[h]:
li[h] = c
for i in t:
n = t.index(i)
print(i,li[n])
print(f'{s[li.index(max(li))]} appears {max(li)} consecutive times')

Here is an O(n) time, O(1) space solution, that breaks ties by returning the earlier seen character:
def get_longest_consecutive_ch(s):
count = max_count = 0
longest_consecutive_ch = previous_ch = None
for ch in s:
if ch == previous_ch:
count += 1
else:
previous_ch = ch
count = 1
if count > max_count:
max_count = count
longest_consecutive_ch = ch
return longest_consecutive_ch, max_count
s = 'aabskeeebadeeee'
longest_consecutive_ch, count = get_longest_consecutive_ch(s)
print(f'{longest_consecutive_ch} appears {count} consecutive times in {s}')
Output:
e appears 4 consecutive times in aabskeeebadeeee

Regex offers a concise solution here:
inp = "aabskeeebadeeee"
matches = [m.group(0) for m in re.finditer(r'([a-z])\1*', inp)]
print(matches)
matches.sort(key=len, reverse=True)
print(matches[0])
This prints:
['aa', 'b', 's', 'k', 'eee', 'b', 'a', 'd', 'eeee']
eeee
The strategy here is to find all islands of similar characters using re.finditer with the regex pattern ([a-z])\1*. Then, we sort the resulting list descending by length to find the longest sequence.

Alternatively, you can leverage the power of itertools.groupby() to approach this type of problem (for quick counting for similar items in groups. [Note, this can be applied to some broader cases, eg. numbers]
from itertools import groupby
>>> char_counts = [str(len(list(g)))+k for k, g in groupby(s)]
>>> char_counts
['2a', '1b', '1s', '1k', '3e', '1b', '1a', '1d', '4e']
>>> max(char_counts)
'4e'
# you can continue to do the rest of splitting, or printing for your needs...
>>> ans = '4e' # example
>>> print(f' the most frequent character is {ans[-1]}, it appears {ans[:-1]} ')
Output:
the most frequent character is e, it appears 4

This answer was posted as an edit to the question Check how many consecutive times appear in a string by the OP Ziggy Witkowski under CC BY-SA 4.0.
I did not want to use any libraries.
s = 'aabskaaaabadcccc'
lil = tuple(set(s)) # Set a characters in s to remove duplicates and
then make a tuple
li=[0,0,0,0,0,0] # list for counted repeats, the index of number
repeats for character
# will be equal to index of its character in a tuple
for i in lil: #iter over tuple of letters
c = 0 #counter
h= lil.index(i) #take an index
for letter in s: #iterate ove the string characters
if letter == i: # check if equal with character from tuple
c += 1 # if equal Counter +1
if c > li[lil.index(letter)]: # Updated the counter if present is bigger than the one stored.
li[lil.index(letter)] = c
else:
c=0
continue
m = max(li)
for index, j in enumerate(li): #Check if the are
characters with same max value
if li[index] == m:
print(f'{lil[index]} appears {m} consecutive times')
Output:
c appears 4 consecutive times
a appears 4 consecutive times

Related

Count number of continuous matching elements in two different numbers in Python

Suppose
we have two numbers a and b we need to calculate the continuous matching digits between the two numbers.
some examples are shown below:
a = 123456 b = 456 ==> I need count as : 3 digits matching
a = 556789 b = 55678 ==> I need count as : 5 digits matching
I don't want unique but continuous matching numbers and need the count. Also display the matching ones will be helpful. Also can we can we do in two different lists if numbers?
I am very new to python and trying out few things. Thanks
Given two numbers a and b:
a = 123456
b = 456
First you need to covert them to strings:
a_str = str(a)
b_str = str(b)
Then you need to check if there is a continuous match of b_str in a_str:
if b_str in a_str:
...
Finally you can check the length of b_str:
len(b_str)
This is the complete function:
def count_matching_elements(a, b):
a_str, b_str = str(a), str(b)
if b_str in a_str:
return len(b_str)
else:
return -1 # no matches
What you want here is know as the Longest common substring, you can find it like this (this code can be found here Find common substring between two strings, just a little difference that you actually want the len(answer)) :
def longestSubstringFinder(string1, string2):
answer = ""
len1, len2 = len(string1), len(string2)
for i in range(len1):
match = ""
for j in range(len2):
if (i + j < len1 and string1[i + j] == string2[j]):
match += string2[j]
else:
if (len(match) > len(answer)): answer = match
match = ""
return len(answer)
Note that a and b would have to be strings

replace an occurrence with a distinct number every loop

The first occurrence of the character in the string will be replaced with a 1, the second occurrence with a 2, etc.
ive tried using for loop and the max function to replace the last occurence but it doesnt seem to work.
string=str(input('string: '))
x=input('character: ')
list=[]
for i in range(len(string)):
if string[i]==x:
list.append(i)
Z=str(max(list))
print(string.replace(x,Z,[::-1]))
the output should be as following
string: departmentofcomputerscience
character: e
d1partm2ntofcomput3rsci4nc5
Here's a way to do it.
Use a counter for each character in the loop, and store values in the list, then merge the list. Use the current value if not equal to the character, counter otherwise:
string=str(input('string: '))
x=input('character: ')
# Use list to store results and a counter
l = []
counter = 0
for c in string:
if c==x:
counter += 1
l.append(str(counter))
else:
l.append(c)
# Merge the resulting list into string
res = "".join(l)
# Output the result
print(res)
For the input string: departmentofcomputerscience
and the character: e
The output is
d1partm2ntofcomput3rsci4nc5
Here is another way to achieve the goal using a list and the method replace():
string = str(input('string: '))
x = input('character: ')
list = []
for i in range(len(string)):
if string[i] == x:
list.append(i) # add all indexes to replace to the list
if len(list) > 0:
j = 0
for i in range(len(list)):
j += 1
string = string.replace(string[list[i]], str(j), 1) # replace the element once at time
print(string)
For string: departmentofcomputerscience
character: e
Output: d1partm2ntofcomput3rsci4nc5
def replace(s, c):
'''
#parameter s: input string
#parameter c: input character to be replaced
#return s: where every occurence of c is
replaced by it's nth occurence
'''
so = list(s)
j = 1
for i in range(len(so)):
if so[i] == c:
so[i] = str(j)
j = j + 1
return ''.join(so)

Dictionary: Check if each element of key & value is equal or not

So I've extracted the source of a html and converted everything into a big dictionary.
This is only an example:
d = {fist:mist}
My goal is to compare the characters by their indexes:
(key[0] & value[0], key[1] & value[1], etc.)
and check if the characters are equal:
f != m, i == i, s==s, t==t
The best I could do:
d = {fist:mist}
difference = 0
no_difference = 0
for key, value in d.items():
for char1 in key:
pass
for char2 in value:
pass
if char1 != char2:
difference += 1
if char1 == char2:
no_difference +=1
print(difference)
print(no_difference)
I appreciate any help.
Edit: Big thanks to Glenn Codes, Joe Iddon and Mike Müller!
You need to loop through the key : value pairs in the dictionary. For each pair, you need to work out how many differences there are between the key and the value. This can be done by working out the length of a list that only contains characters which are different.
We then just add this length to a variable outside the loop to keep track of the total.
d = {"fist":"mist"}
differences = 0
for k, v in d.items():
differences += len([i for i,c in enumerate(k) if c != v[i]])
print(differences)
which, for the small example here, gives 1 as the 'f' and 'm' are different.
If you also want a count of the number of characters which matches (i.e. not different), then you can just do the same process but add the length of the key minus the differences to get the number of characters which were the same:
d = {"fist":"mist"}
differences = 0
same = 0
for k, v in d.items():
differences += len([i for i,c in enumerate(k) if c != v[i]])
same += len(k) - differences
print(differences)
print(same)
which again gives differences as 1, but also gives same as 3 (for 'i', 's' and 't').
If you just wanted a boolean (True / False) value for whether there are any differences between any of the pairs, you can do the whole operation in one line:
all(k == v for k,v in d.items())
which gives False in this case.
Assuming key and value will be the same length you can do:
for key, value in d.items():
for i in range(len(key)):
if key[i] == value[i]:
no_difference +=1
else:
difference += 1
Assuming a dictionary with multiple items and possible different lengths of keys and values, this should work:
from itertools import zip_longest
d = {'fist': 'mist', 'fist1': 'mist22', 'x': 'many differences here'}
difference = 0
no_difference = 0
for k, v in d.items():
for item1, item2 in zip_longest(k, v, fillvalue=''):
if item1 == item2:
no_difference += 1
else:
difference += 1
print('difference:', difference)
print('no_difference:', no_difference)
Output:
difference: 25
no_difference: 6

Return number of alphabetical substrings within input string

I'm trying to generate code to return the number of substrings within an input that are in sequential alphabetical order.
i.e. Input: 'abccbaabccba'
Output: 2
alphabet = 'abcdefghijklmnopqrstuvwxyz'
def cake(x):
for i in range(len(x)):
for j in range (len(x)+1):
s = x[i:j+1]
l = 0
if s in alphabet:
l += 1
return l
print (cake('abccbaabccba'))
So far my code will only return 1. Based on tests I've done on it, it seems it just returns a 1 if there are letters in the input. Does anyone see where I'm going wrong?
You are getting the output 1 every time because your code resets the count to l = 0 on every pass through the loop.
If you fix this, you will get the answer 96, because you are including a lot of redundant checks on empty strings ('' in alphabet returns True).
If you fix that, you will get 17, because your test string contains substrings of length 1 and 2, as well as 3+, that are also substrings of the alphabet. So, your code needs to take into account the minimum substring length you would like to consider—which I assume is 3:
alphabet = 'abcdefghijklmnopqrstuvwxyz'
def cake(x, minLength=3):
l = 0
for i in range(len(x)):
for j in range(i+minLength, len(x)): # carefully specify both the start and end values of the loop that determines where your substring will end
s = x[i:j]
if s in alphabet:
print(repr(s))
l += 1
return l
print (cake('abccbaabccba'))

counting the frequency of a letter in a string

so far this is what i have and this and this will just print out a list with the count of each letter in the string. it only checks for lowercase letters.
`S="""Four score and seven years ago our fathers brought forth on this continent a new nation
Now we are engaged in a great civil war
"""
lowlet = S.lower()
L_count = [0]*26
total_count = 0
alpha = "abcdefghijklmnopqrstuvwxyz"
i = 0
while i < len(lowlet):
if lowlet[i] in alpha:
L_count[i][ord(lowlet[i]) - 97] += 1
total_count += 1
i += 1
print('total count of letters:',total_count)'
now im giving this algorithm but i cant put it into code and i cant use a for loop i have to use a while loop
Initialize a list, L_freq.
For each element, count, in L_counts
Find the letter corresponding to this count
Insert in L_freq, the list: [count, letter]
is it a requirement that it be a list? I feel like a dictionary would be easier to handle
sentence = s.lower()
counts = { letter: sentence.count(letter) for letter in alpha }
print(counts)
this will print like:
{'a': 5, 'b': 2}

Resources