[英]function that reverses a string every time a vowel appears in it?
I'm trying to make a function that, for every occurrence of a vowel in a string, reverses said-string (and includes the vowel when it does this).我正在尝试创建一个函数,对于字符串中每次出现的元音,反转 said-string(并在执行此操作时包括元音)。 The function is somewhat complex for my understanding so I'd like some help and a maybe a breakdown of it.
就我的理解而言,该功能有些复杂,因此我需要一些帮助并可能对其进行细分。 However, I would only like to use the operators and statements that I'm currently learning (for/while and if).
但是,我只想使用我目前正在学习的运算符和语句(for/while 和 if)。 If possible, I would also like to avoid using list comprehension.
如果可能的话,我也想避免使用列表理解。
Here's what the inputs and outputs should look like:输入和输出应该是这样的:
an example input would be reverse_per_vowel('aerith')
which returns 'iraeth'
一个示例输入是
reverse_per_vowel('aerith')
返回'iraeth'
If we break the process of this function into steps, it should look like:如果我们把这个函数的过程分解成几个步骤,它应该是这样的:
( a )erith → ( a )erith ( the first letter is a vowel, so it is reversed. However, because it is the first letter in the string, there are no visible changes. ) ( a )erith → ( a )erith (第一个字母是元音,所以颠倒了。但是,因为它是字符串中的第一个字母,所以没有可见的变化。 )
(a e )rith → ( e a)rith ( the second letter is also a vowel, so every letter in the string leading up to and including the vowel is reversed. ) (a e )rith → ( e a)rith (第二个字母也是元音,所以字符串中直到元音并包括元音的每个字母都被颠倒了。 )
(ear i )th → ( i rae)th ( the fourth letter is a vowel, so everything leading up to and including it is also reversed. Note how it accounts for the letters in the string that were reversed previously. ) (ear i )th → ( i rae)th (第四个字母是元音,所以它之前和包括它的所有内容也被颠倒了。注意它是如何解释字符串中先前被颠倒的字母的。 )
as you can see, the amount of times the string is reversed is cumulative and I'm not quite sure how to code for this.如您所见,字符串反转的次数是累积的,我不太确定如何为此编码。 However, I've attempted to write a component of the function.
但是,我试图编写该函数的一个组件。
What I'm trying我在尝试什么
vowellist = 'aeiouAEIOU'
sampleword = 'aerith'
indexlist = []
for i in range(len(sampleword)):
if sampleword[i] in vowel_list:
indexlist.append(i)
indexlist
output: [0, 1, 3]
输出:
[0, 1, 3]
this excerpt does not reverse any parts of the string, however it returns indexes where the string should be reversed.此摘录不会反转字符串的任何部分,但会返回应反转字符串的索引。 What I planned on doing was plugging these indexes back into the sample word somehow and using [::-1] to reverse a portion of the string.
我计划做的是以某种方式将这些索引插入到示例单词中,并使用 [::-1] 来反转字符串的一部分。 However, I don't know how I would do this nor if it would be a good idea.
但是,我不知道该怎么做,也不知道这是否是个好主意。 Any help would be appreciated.
任何帮助,将不胜感激。
If there are many vowels, then the repeated reversals seem like they could be avoided, as a second reversal somewhat is an undo of the previous reversal.如果有很多元音,那么重复的反转似乎是可以避免的,因为第二次反转在某种程度上是对前一次反转的撤销。
And yes, you could use this algorithm:是的,你可以使用这个算法:
Build two strings.构建两个字符串。 They start emtpy, and mark the second of them as the "active" one.
他们开始是空的,并将其中第二个标记为“活动”。
Visit the input characters in reversed order: from last to first以相反的顺序访问输入的字符:从最后到第一个
At the end of this process, reverse the second string and return the concatenation of the two strings:在此过程结束时,反转第二个字符串并返回两个字符串的串联:
VOWELS = set("aeiouAEIOU")
def reverse_per_vowel(s):
endings = ["", ""]
side = 1
for c in reversed(s):
if c in VOWELS:
side = 1 - side # Toggle between 0 and 1
endings[side] += c
return endings[0] + endings[1][::-1]
As this algorithm is not reversing each time it meets a vowel, but only performs one reversal at the end, it runs with linear time complexity, contrary to what you would get if you implement the described process literally, which has a worst case time complexity of O(n²).由于该算法不会在每次遇到元音时都反转,而是在最后只执行一次反转,因此它以线性时间复杂度运行,这与您按字面意思执行所描述的过程会得到的结果相反,后者具有最坏情况的时间复杂度O(n²)。
With this complexity analysis I assume that extending a string with a character is a constant time process.通过这种复杂性分析,我假设用字符扩展字符串是一个常数时间过程。 If there is doubt about this, then implement it with two lists of characters, calling
append
and perform a join
at the end of the process to get the final string:如果对此有疑问,则用两个字符列表实现它,调用
append
并在过程结束时执行join
以获得最终字符串:
VOWELS = set("aeiouAEIOU")
def reverse_per_vowel(s):
endings = [[], []]
side = 1
for c in reversed(s):
if c in VOWELS:
side = 1 - side # Toggle between 0 and 1
endings[side].append(c)
return "".join(endings[0] + endings[1][::-1])
One easy way to achieve this is to use recursion:实现此目的的一种简单方法是使用递归:
vowels = set('aeiouAEIOU')
def reverse_per_vowel(s):
if not s: # empty string
return ''
beforelast, last = s[:-1], s[-1]
if last in vowels:
return last + reverse_per_vowel(beforelast)[::-1]
return reverse_per_vowel(beforelast) + last
print(reverse_per_vowel('aerith')) # iraeth
You can do it with simple modification of your for
loop and some advanced slicing:您可以通过简单修改
for
循环和一些高级切片来实现:
vowellist = 'aeiouAEIOU'
sampleword = 'aerith'
for i in range(len(sampleword)):
if sampleword[i] in vowellist:
sampleword = sampleword[i::-1] + sampleword[i + 1:]
print(sampleword)
Every iteration if vowel appears you can just reassign string with new partly reversed.如果出现元音,则每次迭代都可以重新分配新的部分反转的字符串。 Output:
输出:
iraeth
Using a list makes it very easy and clean:使用列表使它变得非常简单和干净:
def reverse_per_vowel(word):
result = []
for letter in word:
result.append(letter)
if letter in 'aeiouAEIOU':
result.reverse()
return ''.join(result)
It's also fast.它也很快。 For your sample word, it was faster than all the other solutions posted so far, and for a word with 1000 letters (
'aerith' * 167
), only @trincot's second solution was a bit faster, the others were 2 to 10 times slower.对于你的示例单词,它比目前发布的所有其他解决方案都快,对于一个有 1000 个字母的单词 (
'aerith' * 167
),只有@trincot 的第二个解决方案快一点,其他的慢 2 到 10 倍. Eventually of course it really loses to trincot's second solution, which at 10,000 letters was about 5 times faster and at 100,000 letters was about 46 times faster.当然,最终它真的输给了 trincot 的第二个解决方案,后者在 10,000 个字母时快了大约 5 倍,在 100,000 个字母时快了大约 46 倍。
And here's another linear-time one, a bit faster than trincot's (tested on strings with up to a million letters).这是另一个线性时间的,比 trincot 的快一点(在包含多达一百万个字母的字符串上测试)。 It puts the letters into a deque so it can efficiently append to the left or to the right.
它将字母放入一个双端队列中,因此它可以有效地附加到左侧或右侧。 And it has a flag that tells whether the result is currently in reverse.
它有一个标志,告诉当前结果是否是反向的。
from collections import deque
def reverse_per_vowel(word):
result = deque()
reverse = False
for letter in word:
if not reverse:
result.append(letter)
else:
result.appendleft(letter)
if letter in 'aeiouAEIOU':
reverse = not reverse
if reverse:
result.reverse()
return ''.join(result)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.