Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按字符频率对字符串排序,按字母顺序断开连接_Python_String_Sorting_Hashmap_Frequency - Fatal编程技术网

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
  • 排序任务(比较器,如CPP),您需要一个自定义排序函数,这样您就可以创建一个新类并实现
    \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,谢谢,:)!