#python #arrays #string #combinations #itertools
#python #массивы #строка #комбинации #itertools
Вопрос:
Учитывая строку s, я хочу найти подстроку длиной k, которая содержит максимальное количество гласных в списке [«a», «e», «i», «o», «u»] Пользователь может ввести строку s и ее длину k. Например, если s = «sfjfio» и k = 3, то выводом должна быть строка «fio». Если у меня есть несколько подстрок, удовлетворяющих этому условию, то выводом должна быть подстрока, которая начинается с наименьшего индекса. Если ни одна из подстрок не удовлетворяет требованиям, я хочу, чтобы на выходе была только исходная строка s обратно. Я начал с этого кода, но я немного запутался и застрял. Кажется, это работает, но не всегда дает правильный ответ, когда я пробую несколько примеров. Я только начал с python несколько дней назад и еще не очень хорошо осведомлен. Любая помощь была бы действительно замечательной!
s = input("please enter s ")
k = input("please enter k ")
from itertools import combinations
allsubstrings = [s[a:b] for a, b in combinations(range(len(s) 1), r = 2)]
#if I am right this should give me all the possible substrings in s
#I will only take the ones of length k and put them in an array
substring = []
for i in allsubstrings:
if len(i) == k:
substring.append(i)
vowels = ["a", "e", "i", "o", "u"]
vowcount = []
#here I create an empty array to store the number of vowels in each substring
#now I will loop over each substring and check if it contains a vowel
#I need to check if it contains each one of my vowels though I am not really sure if my code does that or just checks for one of the vowels
for j in substring:
count = 0
for i in vowels:
if i in j:
count = count 1
vowcount.append(count)
#now I check the maximum number of vowels in a given substring
#since I am looping through the substrings in order their vowel count also gets stored in order in my vowcount array thus I can take the index of the max(vowcount) as the index of the substring j that satisfies the condition
if vowcount:
if max(vowcount) != 0:
print(substring[vowcount.index(int(max(vowcount)))])
else:
print(s)
Комментарии:
1. Пожалуйста, приведите пример ввода, который дает неправильный результат, результат, который вы получаете, и результат, который вы ожидаете вместо этого.
2. В любом случае, я не понимаю, почему вы создаете все подстроки, а затем фильтруете их до подстрок соответствующей длины. Подсказка: можете ли вы придумать математическое правило, учитывая, что ваша подстрока
s[a:b]
и желаемая длинаk
относятсяa
кb
?3. Я бы рекомендовал прочитать ericlippert.com/2014/03/05/how-to-debug-small-programs .
4. @KarlKnechtel Привет, Карл, это неудачный пример: s = ioosdfghjkaeibnffbjfbnfoii при k = 4 вывод должен быть «ioos», но программа возвращает полную строку s обратно
5. На самом деле для части s [a:b] я не совсем понимаю, что означают a или b? (Я только что скопировал его из документации) дает ли диапазон [a:b] мне длину, поскольку длина этого интервала равна длине моих подстрок? если это так, я мог бы сделать [0:k-1] ?
Ответ №1:
Для этого вам не нужны itertools, вы можете просто перебирать все возможные подстроки, которые начинаются с позиций 0
len(s)-k
и имеют k
длину символов. Вам также не нужно сохранять количество гласных для каждой подстроки, просто сохраняйте подстроку всякий раз, когда количество гласных превышает предыдущий максимум. Вы должны объединить свой код в функцию, чтобы упростить вызов различных комбинаций входных данных. Например:
def max_vowels(s, k):
vowels = ['a', 'e', 'i', 'o', 'u']
# initialise our state variables
vmax = -1 # maximum number of vowels seen in a subatring
smax = '' # the substring in which we found the maximum
# iterate over all the possible substrings, which start from positions 0 to len(s)-k
for i in range(len(s)-k 1):
# extract the substring
substr = s[i:i k]
# count the number of vowels
num_vowels = sum(1 if c in vowels else 0 for c in substr)
# is it a new maximum count? if so, update our state
if (num_vowels > vmax):
vmax = num_vowels
smax = substr
# all substrings visited, return the one with the most vowels
return smax
print(max_vowels('sfjfio', 3))
print(max_vowels('ioosdfghjkaeibnffbjfbnfoii', 4))
Вывод:
fio
ioos
Ответ №2:
Вот альтернативный подход, который использует collections.Counter
, если вам не разрешено использовать библиотечные методы, просто добавьте свою собственную логику для подсчета количества гласных в одной строке num_vowels_in_str
ниже:
from collections import Counter
def num_vowels_in_str(s):
ch_counts = Counter(s.lower())
return sum(ch_counts[ch] for ch in "aeiou")
s = input("Please enter s: ")
k = int(input("Please enter k: "))
k_length_substrs = [
s[i:j]
for i in range(len(s))
for j in range(i 1, len(s) 1)
if j - i == k
]
num_vowels_per_substr = [
num_vowels_in_str(substring)
for substring in k_length_substrs
]
max_vowels = max(num_vowels_per_substr)
result_index = next(
i
for i, num_vowels in enumerate(num_vowels_per_substr)
if num_vowels == max_vowels
)
result = k_length_substrs[result_index]
print(result)
Пример использования:
Please enter s: sfjfio
Please enter k: 3
fio