我一直在努力解决这个问题,但我无法解决。
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”。
答案 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,其中显示了如何执行此操作。 (而你实际上甚至不需要那么多; OrderedDict
和Counter
与您的使用无关,因此您可以继承__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