如何删除字符串中的重复字符并根据最长的事件进行打印

时间:2014-08-29 00:24:38

标签: python python-2.7

我一直在努力解决这个问题,但我无法解决。

x="abcaa" # sample input
x="bca" # sample output

我试过这个:

from collections import OrderedDict
def f(x):
    print ''.join(OrderedDict.fromkeys(x))
t=input()
for i in range(t):
    x=raw_input()
    f(x)

上面的代码给出了:

x="abcaa" # Sample input
x="abc" # sample output

更多详情: 样本输入:

 abc
 aaadcea
 abcdaaae

示例输出:

abc
adce
bcdae

在第一种情况下,字符串是=“abcaa”,这里'a'在最后重复最多,因此最后放置所以得到“bca”而在其他情况下,“aaadcea”,这里'a'是在第一次重复最大值,因此它首先被放置,产生“adce”。

3 个答案:

答案 0 :(得分:2)

OrderedDict根本无法帮助您,因为您保留的订单并不是您想要的订单。

如果我理解了您的问题(而且我完全不确定,那么......)您想要的订单是排序订单,使用字符作为排序显示的次数键,所以最常见的字符出现在最后。

因此,这意味着您需要以某种方式将每个字符与计数相关联。您可以使用显式循环和d.setdefault(char, 0)等来实现,但如果查看collections文档,则会在{{1}旁边看到名为Counter的内容,这是一个:

  

用于计算可哈希对象的dict子类

这正是你想要的:

OrderedDict

现在您只需要使用>>> x = 'abcaa' >>> collections.Counter(x) Counter({'a': 3, 'b': 1, 'c': 1}) 函数进行排序:

key

如果您希望这是一个稳定的排序,那么具有相同计数的元素会按照它们首次显示的顺序显示,或者它们首次达到该计数的顺序,那么您需要{ {1}}。您如何同时获得>>> ''.join(sorted(c, key=c.__getitem__)) 'bca' 行为和OrderedDict行为?文档中有recipe,其中显示了如何执行此操作。 (而你实际上甚至不需要那么多; OrderedDictCounter与您的使用无关,因此您可以继承__repr____reduce__并且身体Counter。)

答案 1 :(得分:1)

对你想要的东西做出不同的猜测:

对于每个角色,您希望找到重复次数最多的位置。

这意味着,随着你的进展,你需要跟踪每个角色的两件事:到目前为止它重复次数最多的位置,以及多少。而且你还需要跟踪当前的角色运行。

在这种情况下,OrderedDict是必要的,但这还不够。您需要在找到它们时向OrderedDict添加字符,并在找到更长的运行时删除它们并读取它们,并且还需要在每个键的值中存储计数而不是仅使用{ {1}}为OrderedDict。像这样:

OrderedSet

你可能会注意到这里有一些重复,并且有很多冗长。您可以通过将其分为两个步骤来简化问题:首先将字符串压缩为运行,然后跟踪每个字符的最大运行。感谢迭代器的魔力,这甚至不需要两次完成,第一步可以懒得完成。

另外,因为你仍在使用Python 2.7,因此没有d = collections.OrderedDict() lastch, runlength = None, None for ch in x: if ch == lastch: runlength += 1 else: try: del d[lastch] except KeyError: pass if runlength: d[lastch] = runlength lastch, runlength = ch, 1 try: del d[lastch] except KeyError: pass if runlength: d[lastch] = runlength x = ''.join(d) ,我们必须这样做,然后使用OrderedDict.move_to_end来实现更简洁。

所以:

pop

解决这个问题的另一种方法是使用普通的dict,并存储每个字符的游程长度和位置,然后按位置顺序对结果进行排序。这意味着我们不再需要进行移动到结束的随机播放,我们只是将位置更新为值的一部分:

d = collections.OrderedDict()
for key, group in itertools.groupby(x):
    runlength = len(list(group))
    if runlength > d.get(key, 0):
        d.pop(key, None)
        d[key] = runlength
x = ''.join(d)

但是,我不确定这种改进是否真的会提高可读性,所以我会选择上面的第二个版本。

答案 2 :(得分:0)

这是一个不优雅,丑陋,低效,几乎肯定不是Pythonic的解决方案,但我认为它可以满足您的需求。

t = raw_input('Write your string here: ')

# Create a list initalized to 0 to store character counts
seen = dict()

# Make sure actually have a string
if len(t) < 1:
  print ""
else:
  prevChar = t[0]
  count = 0
  for char in t:
    if char == prevChar:
      count = count + 1
    else:
      # Check if the substring we just finished is the longest
      if count > seen.get(prevChar, 0):
        seen[prevChar] = count
      # Characters differ, restart
      count = 1
    prevChar = char

  # Append last character
  seen[prevChar] = count

  # Now let's build the string, appending the character when we find the longest version
  count = 0
  prevChar = t[0]
  finalString = ""
  for char in t:
    if char in finalString:
      # Make sure we don't append a char twice, append the first time we find the longest subsequence
      continue
    if char == prevChar:
      count = count + 1
    else:
      # Check if the substring we just finished is the longest
      if count == seen.get(prevChar, 0):
        finalString = finalString + prevChar
      # Characters differ, restart
      count = 1
    prevChar = char

  # Check the last character
  if count == seen[prevChar]:
    finalString= finalString + prevChar

  print finalString