Python 比较一个字符串[i]与另一个字符串[i]的重复项

Python 比较一个字符串[i]与另一个字符串[i]的重复项,python,python-3.x,Python,Python 3.x,所以程序要求两个字符串。程序应该返回text1,其中每个秘密字母都放在括号中。因此,如果你只读出括号中text1的字母,你就会得到密文 示例 enter text: qmweortnasdftzxcvyqwer enter secret: monty q[m]we[o]rt[n]asdf[t]zxcv[y]qwer enter text: amaoa enter secret: monty python a[m]a[o]a enter text: abcmasoaasnaataayas as

所以程序要求两个字符串。程序应该返回text1,其中每个秘密字母都放在括号中。因此,如果你只读出括号中text1的字母,你就会得到密文

示例

enter text: qmweortnasdftzxcvyqwer
enter secret: monty
q[m]we[o]rt[n]asdf[t]zxcv[y]qwer

enter text: amaoa
enter secret: monty python
a[m]a[o]a

enter text: abcmasoaasnaataayas aspasyastashasoasnas
enter secret:monty
abc[m]as[o]aas[n]aa[t]aa[y]as aspas[y]astashasoasnas

代码

text = input("enter text: ")
secret = input("enter secret text: ")
len_text = len(text)
len_secret = len(secret)
final_answer = ""

for i in range(len_text):

    for k in range(len_secret):
        if secret[k] == text[i] and secret[k] not in final_answer:
            final_answer += "[" + secret[k] + "]"

    if text [i] not in final_answer: 
        final_answer += text[i]


print(final_answer)

代码错误

我试过几种不同的方法,但这是我能想出的最接近答案的代码。我尝试过的所有其他方法最终都会有更多的字母或重复

enter text: monty python
enter secret: monty python

 [m][o][n][t][y][ ][p][h]<<<my output
 [m][o][n][t][y][ ][p][y][t][h][o][n]<<<expected output

enter text:   aamaonataayaa paaayatahaaaoaanaaaaapp
enter secret text:  monty python

a[m][o][n][t][y][ ][p][h]<<<my output
aa[m]a[o][n]a[t]aa[y]aa[ ][p]aaa[y]a[t]a[h]aaa[o]aa[n]aaaaapp<<<expected output

enter text: abcmasoaasnaataayas aspasyastashasoasnas
enter secret:monty

abc[m]as[o]aas[n]aa[t]aa[y]as aspasyastashasoasnas<<<your output
abc[m]as[o]aas[n]aa[t]aa[y]as aspas[y]astashasoasnas<<<expected output
输入文本:monty python
输入秘密:巨蟒

[m] [o][n][t][y][[p][h]这里的根本问题是你在用集合来思考

首先,一封信要么是
secret
的成员,要么不是。因此,
secret
中的每个字母无论出现多少次都是
secret
的成员,因此你最终会有太多重复的字母-
hello
lo
将给你
he[l][l][o]
而不仅仅是
he[l]l[o]

您试图通过使用另一个集合来修复此问题,该集合是迄今为止使用的字母集合,但存在相同的问题:一个字母到目前为止已被使用,或者尚未使用。因此,现在你只能使用每个字母一次,即使它在
secret
中多次出现,而且你根本没有重复:
hello
hello
给你
[h][e][l]l[o]
而不是
[h][e][l][o]

关键是
secret
不是一个集合,而是一个多集合:字母不只是出现或不出现,而是出现一定次数。您希望在
secret
中使用每个字母的次数与其出现的次数相同,而不是无限次,而不是一次。要做到这一点,唯一的方法是记录它出现了多少次,以及您使用过多少次


要解决这个问题,最小的改变就是删除找到的每个字母。像这样:

for letter in text:
    if letter in secret:
        secret = secret.remove(letter, 1) # use it up
        final_answer += "[" + letter + "]"
    else:
        final_answer += letter

但一个更好的解决方案是将秘密信件实际存储为多集。这正是我们要做的:

表面上看,这没什么不同,但如果你看看封面下发生的事情,就会简单得多

secret
是字符串时,
if-letter in secret
实际上必须搜索字符串的每个字符,并将其与
letter
进行比较。然后,
secret.remove(letter,1)
必须再次搜索字符串以找到相同的字母,然后它必须将减去该字母的整个字符串复制到新字符串中才能返回给您

secret
是一个计数器时,
if letter in secret
只需在哈希表中查找
letter
,并检查那里的数字。然后,
secret[letter]-=1
只是将数字递减。我们不需要两次线性搜索和一次线性复制,而是直接查找和减法

当然,在这种情况下,性能不太重要。Python封装了所有线性搜索和复制,因此看起来很容易,即使在封面下发生的事情不是这样。所以,如果您很难理解计数器是如何工作的,或者多集是什么,请不要因为坚持使用字符串而感到太难过,但请记下笔记,稍后再回来,看看一旦您学到更多,是否可以看到差异


然而,尽管这正确地解决了所有示例,但我仍然不确定您是否正确地描述了问题。只有当
secret
中的所有字母出现的顺序与
text
中的顺序相同时,才能“读出机密文本”。在你所有的例子中都是这样的,但是对于
abcdeabcde
db
,什么是正确的答案呢?它应该是
a[b]c[d]eabcde
,还是应该是
abc[d]ea[b]cde

如果是后者,而且
secret
的顺序很重要,那么我们不需要集合或多集合,我们需要列表。我们每次只想检查它的第一个字母

因此,最小的变化是:

for letter in text:
    if secret and secret[0] == letter:
        secret = secret[1:] # use it up
        final_answer += "[" + letter + "]"
    else:
        final_answer += letter
注意,我在检查
secret[0]==letter
之前先检查
secret
。这是因为,当我们用完了
secret
中的所有字母后,就没有了
secret[0]
,因此我们可以使用
索引器


当然,不再进行双线性搜索,但每次我们仍然复制字符串。一个更干净的解决方案是使用一个列表,其中仅弹出最后一个值是瞬时的:

secret = list(secret)[::-1]
for letter in text:
    if secret and secret[-1] == letter:
        secret.pop() # use it up
        final_answer += "[" + letter + "]"
    else:
        final_answer += letter

这里的根本问题是你在用集合来思考

首先,一封信要么是
secret
的成员,要么不是。因此,
secret
中的每个字母无论出现多少次都是
secret
的成员,因此你最终会有太多重复的字母-
hello
lo
将给你
he[l][l][o]
而不仅仅是
he[l]l[o]

您试图通过使用另一个集合来修复此问题,该集合是迄今为止使用的字母集合,但存在相同的问题:一个字母到目前为止已被使用,或者尚未使用。因此,现在你只能使用每个字母一次,即使它在
secret
中多次出现,而且你根本没有重复:
hello
hello
给你
[h][e][l]l[o]
而不是
[h][e][l][o]

关键是
secret
不是一个集合,而是一个多集合:字母不只是出现或不出现,而是出现一定次数。您希望在
secret
中使用每个字母的次数与其出现的次数相同,而不是无限次,而不是一次。要做到这一点,唯一的方法是记录它出现了多少次,以及您使用过多少次


要解决这个问题,最小的改变就是删除找到的每个字母。像这样:

for letter in text:
    if letter in secret:
        secret = secret.remove(letter, 1) # use it up
        final_answer += "[" + letter + "]"
    else:
        final_answer += letter

但更好的解决办法是