Python 按字符频率对字符串排序,按字母顺序断开连接
我想解决这个问题: 给定一个输入字符串,按频率降序对字符进行排序。如果有多个字符具有相同的频率计数,则按字典顺序递增对其进行排序。例如:Python 按字符频率对字符串排序,按字母顺序断开连接,python,string,sorting,hashmap,frequency,Python,String,Sorting,Hashmap,Frequency,我想解决这个问题: 给定一个输入字符串,按频率降序对字符进行排序。如果有多个字符具有相同的频率计数,则按字典顺序递增对其进行排序。例如: bdca --> abcd, bdcda -> ddabc, abba -> aabb, bacbdc -> bbccad, 我的解决方案包括在哈希映射中创建频率,使用sorted()和lambda函数按频率对哈希映射dict项进行排序。然后对于具有相同频率的项(我需要为此编写一个子例程),我使用lambda函数进行另一次排序 def
bdca --> abcd,
bdcda -> ddabc,
abba -> aabb,
bacbdc -> bbccad,
我的解决方案包括在哈希映射中创建频率,使用sorted()和lambda函数按频率对哈希映射dict项进行排序。然后对于具有相同频率的项(我需要为此编写一个子例程),我使用lambda函数进行另一次排序
def string_sort(s):
hmap = {}
for char in s:
if char not in hmap:
hmap[char] = 1
else:
hmap[char] += 1
freqs = sorted(hmap.items(), key=lambda x: x[1], reverse=True)
num_occur: list = find_num_occur(freqs)
sorted_freqs = []
start_ind = 0
for f in num_occur:
tmp_freqs = sorted(freqs[start_ind : start_ind + f], key=lambda x: x[0])
sorted_freqs.extend(tmp_freqs)
start_ind = len(sorted_freqs)
out = []
for item in sorted_freqs:
out.extend([item[0]] * item[1])
return "".join(out)
def find_num_occur(freqs):
count = 1
out = []
for i in range(len(freqs) - 1):
if freqs[i][1] == freqs[i + 1][1]:
count += 1
else:
out.append(count)
count = 1
out.append(count)
return out
解决方案并不优雅。有人告诉我,如果使用比较器,我可以更轻松地解决这个问题,但我不知道如何在python中使用比较器。有什么建议吗?还是其他更优雅的解决方案
谢谢。您不需要使用比较器,您可以很好地使用按键功能。您的解决方案中存在许多不必要的复杂性,您所需要的只是以下效果:
>>> from collections import Counter
>>> def transmogrify(s):
... counts = Counter(s)
... return ''.join(sorted(s, key=lambda c: (-counts[c], c)))
...
>>> transmogrify('bdca')
'abcd'
>>> transmogrify('bdcda')
'ddabc'
>>> transmogrify('abba')
'aabb'
>>> transmogrify('bacbdc')
'bbccad'
注意,collections.Counter
只是一个专门用于计数的dict
,因为它是一种非常常见的模式
>>> Counter('bacbdc')
Counter({'b': 2, 'c': 2, 'a': 1, 'd': 1})
计数器和lt方法
我认为你的任务可以分为两项:
计数器
类轻松实现,但计数器
无法保证其键的顺序,因此需要任务2\uu lt\uu
方法从集合导入计数器
类别项目:
定义初始(自我、通道、时间):
self.ch=ch
self.times=次
定义(自身、其他):
如果self.times>other.times:
返回真值
如果self.times==其他.times:
返回self.ch
下面是一个非常优雅的工具(具有相同的能力),谢谢他
def重构(inp):
c=计数器(inp)
返回“”。连接(已排序(inp,key=lambda-ch:Item(ch,c[ch]))
然后尝试重构('bacbdc')get
bbccad
,宾果 这回答了你的问题吗?关于词汇:“词典顺序”对单个字符没有意义。你可能是指“字母顺序”。“词典编纂顺序”是关于比较序列的。或者,你可以使用<代码>计数器。MistuyUng/<代码>重新扩展到原件,因为它将返回最常见的元素,例如“代码>”。连接(L*n为n,n为计数器(s)。MOSTYUM())< /代码>不,不能仅使用计数,考虑<代码> 'CCBB '< /Cord>。用你所拥有的,它只会返回'ccbb'
,但它应该返回'bbcc'
是的,你是对的,我错过了词法排序的回退。谢谢你的回复@juanpa.arrivillaga我想问题是我不太理解您在这里提供的键函数:key=lambda c:(-counts[c],c)
。你能解释一下这两个参数是什么意思吗?谢谢。@Martin,这不是两个论点。这是一个元组,元组中的第一项,包含该字符的计数(嗯,是负数,因为您希望按降序排序,默认情况下,按升序排序),第二个元素包含该字符。元组按字典顺序排序。因此,首先它比较元组的第一个元素,如果有一个平局,它比较第二个元素(以此类推,例如(1,'b')<(1,'c')
,就像'ab'
)你可以使用排序(inp,key=lambda-ch:Item(ch,c[ch])
酷!!!非常优雅,现在我知道排序
func的键
arg,谢谢,:)!