Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用嵌套for循环和if语句将字符替换为整数_Python_String_For Loop - Fatal编程技术网

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
    设置为
    a-1rdvark
    。文本现在有9个字符长,因此最后一个
    r
    将永远不会被检查(最多循环到
    i=6
    );如果测试字符串以双字母结尾,这将是一个问题。您中断了循环,因此的
    j
    循环永远不会到达第三个
    a
    ,第二个
    a
    无法再进行测试,因为它已被替换

  • 您的代码找到
    -
    (不重复),
    1
    (不重复),然后找到
    r
    (重复一次),因此现在您将
    文本替换为
    a-1rdva-4k
    。现在您有了一个10个字符的字符串,因此将永远不会测试
    -
    4
    。这已经不是什么大问题了,但如果字符串的最后3个位置出现重复会怎么样

为输出构建一个新对象(添加以前未见过的字母和反向引用)。这样你就不会导致你正在循环的文本增长,你会继续发现重复;对于括号,可以使用更多的字符串连接。您需要扫描
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})将执行表达式,并将结果放入一个字符串中,该字符串中也包含
    字符。对于早期的Python版本,可以使用[
    str.format()
    方法](https://docs.python.org/3/library/stdtypes.html#str.format)得到同样的结果;然后,语法变成
    “({})”格式(some-calculation+或*other)`

加在一起,就变成:

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