How to check the number of substrings in string s that contains both string a and b? For example if input is :ab c cabc . Answer should come as 3 as cabc has 3 substrings that include both ab and c : cab, cabc, abc.
a = 'ab'
b = 'c'
c = 'cabc'
total = 0
substring = []
substring.append(c)
for counter in range (0,len(c)):
substring.append(c[counter:len(c)])
for i in substring:
if a in i and b in i:
total += 1
print(total)
Pretty much you can find every single substring then check all of them. Ineffective, but It worked for your test case and some extra I checked. Hope this helps!
Related
I am creating a program that prints the number of unique vowels in a string, whether upper or lower case. For example: "swEet” would print 1. What I have so far prints the number of vowels but not unique ones. What can I change or add to my code to do this? Thank you. I'm a beginner in Python and coding.
import sys
def count_vowels(sys_str):
sys_str = sys.argv[1].upper()
vowels = 'aeiou'
count = len([c for c in sys_str.lower() if c in
vowels])
return count
sys_str = sys.argv[1].upper()
count = count_vowels(sys_str)
print(count)
Source: DBrowne's answer at Counting the number of vowels in a string using for loops in Python I got some of my code from this user in this question.
First off Eat actually has 2 vowels "E" and "a".
Second You won't need to use the sys module
You can simplify your code to this if you're just trying to find the vowels in a string:
def count_vowels(sys_str):
vowels = 'aeiou'
count = len([c for c in sys_str.lower() if c in vowels])
return count
As for finding unique vowels you can write something like this:
def count_vowels(string):
vowels = 'aeiou'
hashmap = {}
array = []
for i, c in enumerate(string.lower()):
if c not in hashmap:
array.append(c)
hashmap[c] = i
else:
array.pop(hashmap[c])
return len(array)
Example:
count_vowels('Eeat')
Output: 1 #<- This is because there are 2 e's now so a is the only unique vowel
Obviously, there's a lot more efficient time and space solution out there. This is just something off the top of my head. Hopes This helps!
Is there a requirement that you use for loops? The set type is much better suited to this type of problem -- no iteration necessary (at least in Python, there's obviously still iteration on the back end in C).
VOWELS = set("aeiou")
def count_vowels(s: str) -> int:
return len(VOWELS.intersection(s.lower()))
Examples:
In [6]: count_vowels("Eat")
Out[6]: 2
In [7]: count_vowels("sweEt")
Out[7]: 1
In [8]: count_vowels("hello")
Out[8]: 2
In [9]: count_vowels("aeiou")
Out[9]: 5
In [10]: count_vowels("aeiou"*10)
Out[10]: 5
In [11]: count_vowels("")
Out[11]: 0
In [12]: count_vowels("syzygy")
Out[12]: 0
I want to ask if there is a better way to check the number of characters matches for two different string. For example when I input the word 'succeed' I want to know how many characters does it match the word 'success' at the exact position. In this case, 'succeed' matches 5 out of 7 characters of 'success'. This function is needed to be implemented into a bigger project. Right now I have a proof of concept python code:
word1 = input('Enter word1>')
word2 = input('Enter word2>')
#word1 is being compared to word2
word1_character_list = list(word1)
word2_character_list = list(word2)
matching_word_count = 0
for index in range(0,len(word2)):
if word1_character_list[index] == word2_character_list[index]:
matching_word_count = matching_word_count + 1
print(matching_word_count)
I wonder if there is a simpler and/or shorter way to do it? Or a way that use less variables. Any help will be appreciated.
You can iterate through two strings simultaneously using the zip function. Also, its considered to be more pythonic to iterate through items in a list and compare the values rather than indexing the list.
For example:
>>> word1 = 'success'
>>> word2 = 'succeed'
>>> matches = 0
>>> for letter1, letter2 in zip(word1, word2):
if letter1 == letter2:
matches +=1
>>> matches
5
If you wanted to get really creative you could do it in one line:
>>> matches = sum([l1 == l2 for l1, l2 in zip(word1, word2)])
>>> matches
5
matching_word_count = sum(map(str.__eq__, word1, word2))
Or more readable:
matching_word_count = sum(c1 == c2 for c1, c2 in zip(word1, word2))
This is because booleans are a subclass of integers in Python, with True == 1 and False == 0.
You could change your for loop to something like this:
for i, j in zip(word1, word2):
if i != j:
break
matching_word_count += 1
This code starts from the first character and breaks as soon as a character is not the same. If every character needs to be checked, then the code can be easily modified to (as in other answers):
for i, j in zip(word1, word2):
if i == j:
matching_word_count += 1
Here is another oneliner using inbuilt zip function :
matches = len([c for c,d in zip(word1,word2) if c==d])
I don't know what kind of problem this is called and couldn't find something related to this on the site. I am trying to make a function that prints out the first letter of the word on the first line then the next two letters and so on. However, I am not sure on how to prevent repeating the complete word. For example in the word 'bar', it should go
b
ba
bar
ba
b
but my function repeats bar twice. Thanks!
a= []
def letters():
x = input("Enter a string")
count = 0
for c in x:
count +=1
y = 0
while y <= count:
z = (x[:y])
a.append(z)
y += 1
negWords = a[::-1]
for words in a:
print (words)
for words in negWords:
print (words)
You seem to be doing some unnecessary work for simply wanting to print something. You can make use of len to get the length of the word, without having to go through a loop to get the size.
Also, collecting the data in a list seems unnecessary.
To stick to the nature of your approach with the while loop, you can go through the entire length of the word and back again until "0". So, to me, I see that as twice the length of the word. With that in mind, that would be my control for the while loop. I would simply then check for when my incrementer reaches about the length of the word, and start going backwards from there:
w = "bar"
l = len(w)
i = 0
while i <= l*2:
if i > l:
print(w[:(l - i)])
else:
print(w[:i])
i += 1
Output:
b
ba
bar
ba
b
Try this:
negWords= a[:-1:-1]
This will not include the full word a second time
Also, your code could use a lot of cleanup. For example:
count = len(x)
Makes more sense than what you have
I'm taking MIT 6.00.1x from edX.org and I'm on problem set 1 problem 2. I'm having trouble getting bob from this variable
s = 'azcbobobegghakl'
I have this code
s = 'azcbobobegghakl'
bobTimes = 0
for bobWord in s:
if 'b' and 'o' and 'b' in bobWord:
bobTimes += 1
print(bobTimes)
The code works for this variable, but when you add on another b and o, like this:
s = 'azcbobobegghaklbobddbtto'
It adds one to the bobTimes variable. I don't see how I can extract the word 'bob' from this variable.
Just get the next 3 characters of the string using python's list slices.
s = 'azcbobobegghakl' #prints 2
s = 'azcbobobegghaklbobddbtto' #prints 3
bobTimes = 0
for i in range(len(s)):
if s[i:i+3] == 'bob':
bobTimes += 1
print(bobTimes)
Could you clarify the extraction requirements? Specifically:
is bobob two bobs, or just one? is bobobob three? or must they all be seperate i.e. bobasdfbobwwwwbob
s.count("bob") would count how many instances of "bob" occur with non overlapping letters. i.e bob is 1, bobbob is 2, bobob is only one because the middle b only counts towards the first one, leaving only ob, but bobobob is 2 better read as bob o bob
you could iterate through the characters one at a time, and check if that character and the next 3 are equal to "bob"
for k,v in enumerate(s):
if s[k:k+3]=="bob": bobcount+=1
this approach counts bobob as two, and bobobob as three.
or you could resort to using regular expressions, but thats not my strong suit, and i'll leave that to someone else to explain/update a bit later with info on that.
For a homework assignment, I have to take 2 user inputted strings, and figure out how many letters are common (in the same position of both strings), as well as find common letters.. For example for the two strings 'cat' and 'rat', there are 2 common letter positions (which are positions 2 and 3 in this case), and the common letters are also 2 because 'a' is found one and 't' is found once too..
So I made a program and it worked fine, but then my teacher updated the homework with more examples, specifically examples with repetitive letters, and my program isn't working for that.. For example, with strings 'ahahaha' and 'huhu' - there are 0 common letters in same positions, but there's 3 common letters between them (because 'h' in string 2 appears in string 1, three times..)
My whole issue is that I can't figure out how to count if "h" appears multiple times in the first string, as well as I don't know how to NOT check the SECOND 'h' in huhu because it should only count unique letters, so the overall common letter count should be 2..
This is my current code:
S1 = input("Enter a string: ")
S2 = input("Enter a string: ")
i = 0
big_string = 0
short_string = 0
same_letter = 0
common_letters = 0
if len(S1) > len(S2):
big_string = len(S1)
short_string = len(S2)
elif len(S1) < len(S2):
big_string = len(S2)
short_string = len(S1)
elif len(S1) == len(S2):
big_string = short_string = len(S1)
while i < short_string:
if (S1[i] == S2[i]) and (S1[i] in S2):
same_letter += 1
common_letters += 1
elif (S1[i] == S2[i]):
same_letter += 1
elif (S1[i] in S2):
common_letters += 1
i += 1
print("Number of positions with the same letter: ", same_letter)
print("Number of letters from S1 that are also in S2: ", common_letters)
So this code worked for strings without common letters, but when I try to use it with "ahahaha" and "huhu" I get 0 common positions (which makes sense) and 2 common letters (when it should be 3).. I figured it might work if I tried to add the following:
while x < short_string:
if S1[i] in S2[x]:
common_letters += 1
else:
pass
x += 1
However this doesn't work either...
I am not asking for a direct answer or piece of code to do this, because I want to do it on my own, but I just need a couple of hints or ideas how to do this..
Note: I can't use any functions we haven't taken in class, and in class we've only done basic loops and strings..
You need a data structure like multidict. To my knowledge, the most similar data structure in standard library is Counter from collections.
For simple frequency counting:
>>> from collections import Counter
>>> strings = ['cat', 'rat']
>>> counters = [Counter(s) for s in strings]
>>> sum((counters[0] & counters[1]).values())
2
With index counting:
>>> counters = [Counter(zip(s, range(len(s)))) for s in strings]
>>> sum(counters[0] & counters[1].values())
2
For your examples ahahaha and huhu, you should get 2 and 0, respectively since we get two h but in wrong positions.
Since you can't use advanced constructs, you just need to simulate counter with arrays.
Create 26 elements arrays
Loop over strings and update relevant index for each letter
Loop again over arrays simultaneously and sum the minimums of respective indexes.
A shorter version is this:
def gen1(listItem):
returnValue = []
for character in listItem:
if character not in returnValue and character != " ":
returnValue.append(character)
return returnValue
st = "first string"
r1 = gen1(st)
st2 = "second string"
r2 = gen1(st2)
if len(st)> len(st2):
print list(set(r1).intersection(r2))
else:
print list(set(r2).intersection(r1))
Note:
This is a pretty old post but since its got new activity,I posted my version.
Since you can't use arrays or lists,
Maybe try to add every common character to a var_string then test
if c not in var_string:
before incrementing your common counter so you are not counting the same character multiple times.
You are only getting '2' because you're only going to look at 4 total characters out of ahahaha (because huhu, the shortest string, is only 4 characters long). Change your while loop to go over big_string instead, and then add (len(S2) > i) and to your two conditional tests; the last test performs an in, so it won't cause a problem with index length.
NB: All of the above implicitly assumes that len(S1) >= len(S2); that should be easy enough to ensure, using a conditional and an assignment, and it would simplify other parts of your code to do so. You can replace the first block entirely with something like:
if (len(S2) > len(S1)): (S2, S1) = (S1, S2)
big_string = len(S1)
short_string = len(S2)
We can solve this by using one for loop inside of another as follows
int y=0;
for(i=0;i<big_string ;i++)
{
for(j=0;j<d;j++)
{
if(s1[i]==s2[j])
{y++;}
}
If you enter 'ahahaha' and 'huhu' this code take first character of big
string 'a' when it goes into first foor loop. when it enters into second for loop
it takes first letter of small string 'h' and compares them as they are not
equal y is not incremented. In next step it comes out of second for loop but
stays in first for loop so it consider first character of big string 'a' and
compares it against second letter of small string 'u' as 'j' is incremented even
in this case both of them are not equal and y remains zero. Y is incremented in
the following cases:-
when it compares second letter of big string 'h' and small letter of first string y is incremented for once i,e y=1;
when it compares fourth letter of big string 'h' and small letter of first string y is incremented again i,e y=2;
when it compares sixth letter of big string 'h' and small letter of first string y is incremented again i,e y=3;
Final output is 3. I think that is what we want.