Python 使用嵌套for循环和if语句将字符替换为整数
我需要输出任何重复的字符来引用前一个字符 例如:Python 使用嵌套for循环和if语句将字符替换为整数,python,string,for-loop,Python,String,For Loop,我需要输出任何重复的字符来引用前一个字符 例如:a(-1)rdv(-4)k或hel(-1)o 这是我目前的代码: text= 'aardvark' i=0 j=0 for i in range(len(text)-1): for j in range(i+1, len(text)): if text[j]==text[i]: sub= text[j] val2=text.find(sub, i+1, len(text))
a(-1)rdv(-4)k
或hel(-1)o
这是我目前的代码:
text= 'aardvark'
i=0
j=0
for i in range(len(text)-1):
for j in range(i+1, len(text)):
if text[j]==text[i]:
sub= text[j]
val2=text.find(sub, i+1, len(text))
p=val2+1
val=str(i-j)
text= text[:val2] + val + text[p:]
break
print(text)
输出:a-1rdva-4k
第二个
'a'
无法识别。而且我不知道如何在我的打印中包含括号。通过每次找到反向引用时更新文本,你会弄脏索引(每次文本都会变长),而且你永远不会正确处理最后的字符。当您发现“当前”字符的第一次重复时,您将停止检查,因此第三次a
将永远不会被处理。这适用于输入字符串中每三次重复一次。此外,如果您的输入文本包含任何-
字符或数字,它们最终将根据您在它们前面插入的-偏移量
引用进行测试
对于aardvark
(一个包含8个字符的字符串)的特定示例,发生的情况如下:
- 找到第二个
并将a
设置为text
。文本现在有9个字符长,因此最后一个a-1rdvark
将永远不会被检查(最多循环到r
);如果测试字符串以双字母结尾,这将是一个问题。您中断了循环,因此的i=6
j
循环永远不会到达第三个
,第二个a
无法再进行测试,因为它已被替换a
- 您的代码找到
(不重复),-
(不重复),然后找到1
(重复一次),因此现在您将r
文本替换为
。现在您有了一个10个字符的字符串,因此将永远不会测试a-1rdva-4k
和-
。这已经不是什么大问题了,但如果字符串的最后3个位置出现重复会怎么样4
i
之前的字符串部分,而不是之后的字符串部分,才能使其正常工作,然后返回!测试i-1
,i-2
等,下降到0。当然,这意味着您的i
循环的范围应达到整个长度:
output = ''
for i in range(len(text)):
current = text[i]
for j in range(i - 1, -1, -1):
if text[j] == current:
current = '(' + str(j - i) + ')'
break
output = output + current
print(output)
我在这里将修复保持在最低限度,但理想情况下,我还将进行更多更改:
- 将所有处理过的字符和引用添加到新列表中,而不是字符串,然后使用
将该列表连接到输出中。这比每次迭代重建字符串要有效得多str.join()
- 使用两个循环意味着在文本上循环时再次检查字符串中的每个字符,因此算法所采取的步骤数随输入长度呈指数增长。在计算机科学中,我们讨论算法的时间复杂度,你的是一个O(N^2)(N平方)指数算法。一个包含1000个字母的文本将需要多达100万个步骤来处理!您可以使用字典来跟踪您所看到的字母的索引,而不是指数级循环次数。如果当前字符在字典中,则可以简单地计算偏移量。字典查找需要固定的时间(O(1)),使得整个算法需要线性时间(O(N)),这意味着该过程所需的时间与输入字符串的长度成正比
- 用于向循环添加计数器,以便直接循环字符,无需使用
range()
- 您可以使用字符串格式来构建
字符串;Python3.6和更新的版本有,其中“()”
字符串采用的f'…'
占位符仅仅是表达式{}
(f'({some-calculation+或*other})将执行表达式,并将结果放入一个字符串中,该字符串中也包含
)和
str.format()字符。对于早期的Python版本,可以使用[
“({})”格式(some-calculation+或*other)`方法](https://docs.python.org/3/library/stdtypes.html#str.format)得到同样的结果;然后,语法变成
def add_backrefs(text):
output = []
seen = {}
for i, character in enumerate(text):
if character in seen:
# add a back-reference, we have seen this already
output.append(f'({seen[character] - i})')
else:
# add the literal character instead
output.append(character)
# record the position of this character for later reference
seen[character] = i
return ''.join(output)
演示:
输出:
a(-1)rdv(-4)(-4)k
@MartijnPieters python版本并没有明确说明,很多人都不知道f字符串只支持python3.6及以上版本(初学者可能需要一个解释或兼容的答案!!)我已经开始编写了几周的代码,在我的主题中,我们还没有涵盖上述内容。我们对循环、if、else等基本元素使用嵌套。我不确定这个版本,因为它是我们工作的一个内置uni环境。@MartijnPieters这正是我想到的更好的解决方案。好的job@RaquelBisogno当前位置我已经包括了一个更详细的解释,说明你错在哪里。这有助于你更好地理解它吗?@RaquelBisogno:我现在为你添加了一个固定的“简单”版本,进一步解释了双循环版本是如何工作的。为什么第三个a是
(-4)
,而不是(-5)
?是否应该引用上一个位置而不是第一个位置?必须引用上一个重复字母。在aardvark中,最后一个a应提交给第二个a(以前的信函实例)支票,谢谢确认!
text= 'aardvark'
d={} # create a dictionary to keep track of index of element last seen at
new_text='' # new text to be generated
for i in range(len(text)): # iterate in text from index 0 up to length of text
c = text[i] # storing a character in temporary element as used frequently
if c not in d: # check if character which is explored is visited before or not
d[c] = i # if character visited first time then just add index value of it in dictionary
new_text += c # concatenate character to result text
else: # visiting alreaady visited character
new_text += '({0})'.format(d[c]-i) # used string formatting which will print value of difference of last seen repeated character with current index instead of {0}
d[c] = i # change last seen character index
print(new_text)
a(-1)rdv(-4)(-4)k