【发布时间】:2020-06-16 19:17:59
【问题描述】:
所以,我在 IT 课上做了一个类似的练习:“打印一个没有出现多次的字符的字符串(如果出现多次,删除它们)”。我认为这很容易(也许确实如此),但我完全不知道该怎么做。我可以做类似的练习(打印字符串中的所有唯一字符/删除重复项等)。
例子:
输入:'12345555555678'
输出:'1234678'
【问题讨论】:
所以,我在 IT 课上做了一个类似的练习:“打印一个没有出现多次的字符的字符串(如果出现多次,删除它们)”。我认为这很容易(也许确实如此),但我完全不知道该怎么做。我可以做类似的练习(打印字符串中的所有唯一字符/删除重复项等)。
例子:
输入:'12345555555678'
输出:'1234678'
【问题讨论】:
这应该看起来像你想要的
input_str = 'ahuadvzudnioqdazvyduazdazdui'
for c in input_str:
if input_str.count(c)==1:
print(c)
它更容易理解,但请注意它的性能相当低(O(n^2) 的复杂度)。
为了加快速度,您可以使用列表理解。
input_str = '12345555555678'
[x for x in input_str if input_str.count(x) == 1]
如果元素的顺序对您来说并不重要,那么迭代列表集将是有益的。
如果您使用set(input_str) 将列表转换为集合,那么它将具有唯一值,这可能最终会减少搜索空间。
然后你可以应用列表complrehension。
input_str = '12345555555678'
[x for x in set(input_str) if input_str.count(x) == 1]
注意:不要忘记转换为set后不保留顺序的条件。
【讨论】:
from collections import Counter
inp = '12345555555678'
c = Counter(inp)
output = ''.join(k for k, v in c.items() if v == 1) # -> 1234678
Counter 的简单实现
c = {}
for char in inp:
c[char] = c.get(char, 0) + 1
【讨论】:
此answer 中描述了此基本算法 - 对于每个字符,您可以通过计算它在字符串中的出现次数来检查它是否出现多次。
但是,这是相当低效的,因为它通过字符串 n ^ 2。您可以通过消耗一些内存来改进它(这在 answer 中进行了说明 - 但被库混淆了)。
然后算法将遍历字符串并计算每个字符的出现次数并将它们保存在某处,然后再次遍历字符串并仅打印计数为 1 的字符。
inp = '1345552225555678'
counts = {};
for ch in inp:
if ch in counts:
counts[ch] = counts[ch] + 1
else:
counts[ch] = 1
result = '';
for ch in inp:
if counts[ch] == 1:
result = result + ch
print result
可以说,这将是 O(n),因为字典的访问时间通常被认为是 O(1)(参见 question 进行讨论)
注意:通常这是使用数字合法字符大小的数组来完成的,但是由于 python 中的字符串是 Unicode,所以数组会很大,但是访问时间确实是 O(1);
【讨论】:
i_str = '12345555555678'
b = sorted(i_str)
for i in range(len(b)-1):
if b[i] == b[i+1]:
i_str = i_str.replace(b[i],'')
您只需对字符串进行排序并将每个第 n 个元素与下一个元素进行比较。如果不相同,则它是唯一的。
我也很确定它应该比使用 count 函数更快,该函数将遍历每个唯一元素的所有字符串并检查字符数是否不大于 1。
【讨论】: