从字符串中删除重复项,使其出现一次

时间:2015-12-12 03:39:45

标签: python

给定一个仅包含小写字母的字符串,删除重复的字母,以便每个字母只出现一次。我必须确保你的结果在所有可能的结果中都是字典顺序最小的。

def removeDuplicates(str):
    dict = {}
    word = []
    for i in xrange(len(str)):
        if str[i] not in word:
            word.append(str[i])
            dict[str[i]] = i
        else:
            word.remove(str[i])
            word.append(str[i])
            dict[str[i]] = i

    ind = dict.values()
    # Second scan
    for i in xrange(len(str)):
        if str.index(str[i]) in ind:
            continue
        temp = dict[str[i]]
        dict[str[i]] = i
        lst = sorted(dict.keys(),key = lambda d:dict[d])
        if ''.join(lst) < ''.join(word):
            word = lst
        else:
            dict[str[i]] = temp
    return ''.join(word)

我没有得到理想的结果

print removeDuplicateLetters("cbacdcbc")

Input:
"cbacdcbc"
Output:
"abcd"
Expected:
"acdb"

3 个答案:

答案 0 :(得分:3)

使用set。集合是类似于列表的数据结构,但它会删除所有重复项。您可以通过执行set()实例化集合,或使用大括号将变量设置为集合。但是,这对于实例化空集并不是很好,因为Python会认为它是一个字典。因此,要实现您正在做的事情,您可以执行以下功能:

def removeDuplicates(string):
    return ''.join(sorted(set(string)))

答案 1 :(得分:2)

多利安的回答是实际应用的方法,所以我的补充主要是玩弄。

如果一个单词真的很长,那么只搜索字母表中的每个字母是否在字符串中并且仅保留那些存在的单词更有效。明确地,

from string import ascii_lowercase

def removeDuplicates(string):
    return ''.join(letter for letter in ascii_lowercase if letter in string)

测试时间的代码

import random
import timeit

def compare(string, n):
    s1 = "''.join(sorted(set('{}')))".format(string)
    print timeit.timeit(s1, number=n)
    s2 = "from string import ascii_lowercase; ''.join(letter for letter in ascii_lowercase if letter in '{}')".format(string)
    print timeit.timeit(s2, number=n)

试验:

>>> word = 'cbacdcbc'
>>> compare(word, 1000)
0.00385931823843
0.013727678263
>>> word = ''.join(random.choice(ascii_lowercase) for _ in xrange(100000))
>>> compare(word, 1000)
2.21139290323
0.0071371927042
>>> word = 'a'*100000 + ascii_lowercase
>>> compare(word, 1000)
2.20644530225
1.63490857359

这表明多利安的答案对于小词来说应该表现得同样好甚至更好,即使速度不是人类可以注意到的。但是,对于非常大的字符串,此方法要快得多。即使对于边缘情况,每个字母都是相同的,其余的字母只能通过横切整个字符串找到,它的表现会更好。

尽管如此,多利安的答案仍然更加优雅和实用。

答案 2 :(得分:0)

这就是测试成功的原因。

def removeDuplicates(my_string):
    for char in sorted(set(my_string)):
        suffix = my_string[my_string.index(char):]
        if set(suffix) == set(my_string):
            return char + removeDuplicates(suffix.replace(char, ''))
    return ''

print removeDuplicates('cbacdcbc')

ACDB