2017-06-07 8 views
4

周波数で単純な文字列をソートする際に問題があります(文字列が入力として得られます。ソートされた文字列を出力として戻す必要があります)。降順)。 私は(元の単語が4つのEさん、2秒のの、1トン、1 rと1つのDが含まれている;ので、これらは、ソートされた取得)あなたに例を挙げてみましょう:私は使うべきスタックオーバーフロー状態にPython周波数別に文字列をソートする - ソート済みの関数でソートできない

In [1]: frequency_sort("treeseeds") 
Out [1]: "eeeesstrd" 

ほとんどのソリューションしかし、sorted()は私の結果を得るために機能しますが、特定のケースでしか動作しないようです。

私は機能するはずの2つの機能を作ったが、それらのどれも私の特定の入力(以下を参照)でトリックをしていないようだ。

まず機能:

def frequency_sort(s): 
    s_sorted = sorted(s, key=s.count, reverse=True) 
    s_sorted = ''.join(c for c in s_sorted) 
    return s_sorted 

セカンド機能:

最初の出力は大丈夫です:

import collections 
def frequency_sort_with_counter(s): 
    counter = collections.Counter(s) 
    s_sorted = sorted(s, key=counter.get, reverse=True) 
    s_sorted = ''.join(c for c in s_sorted) 
    return s_sorted 

私の出力は次のようになり、両方の機能を持ちます

In [1]: frequency_sort("loveleee") 
Out [1]: "eeeellov" 

第二の出力は

In [2]: frequency_sort("loveleel") 
Out [2]: "leleelov" 

それほどではない第3の出力は完全に厄介です:

In [3]: frequency_sort("oloveleelo") 
Out [3]: "oloeleelov" 

間違っている可能性は?それはどういうわけか 'o'と 'l'の文字に接続されていますか?それとも、私は何かが足りないのですか?

+0

を3番目の関数を追加するのを忘れてしまった。 –

+0

[リスト内の出現頻度によるリストの並べ替え]の可能な複製(https://stackoverflow.com/questions/23429426/sorting-a-list-by-frequency-of-occurrence-in-a-list) – depperm

答えて

4

複数の文字の頻度が同じ文字列では、提案したアルゴリズムでは同じ回数の文字を区別する方法がありません。あなたは周波数のタプルと文字そのものを使ってソートすることで対処できます。例えばあなたの第三の場合

In [7]: def frequency_sort(s): 
     s_sorted = sorted(s, key=lambda c: (s.count(c), c), reverse=True) 
     s_sorted = ''.join(c for c in s_sorted) 
     return s_sorted 
    ...: 

In [8]: frequency_sort("loveleel") 
Out[8]: 'llleeevo' 
0

3つの文字は、それらが一緒に入れている理由だと同じ数を持って、あなたは(アルファベットで)最初にそれを並べ替えることができますし、次のように文字を配置する周波数によって、それを並べ替える:

s_sorted = ''.join(sorted(sorted(s), key=lambda x: s.count(x), reverse=True)) 

出力:

eeellloooav 

またはあなたはそれを逆にすることができます:

s_sorted = ''.join(sorted(sorted(s, reverse=True), key=lambda x: s.count(x), reverse=True)) 

出力:

ooollleeeva 
0

問題がsortsortedが安定ソートしているということです。したがって、2つの値が「等しい」(この場合はkey(item1) == key(item2))場合は、sortの前と同じ順序で表示されます。例えば

あなたが持っているあなたの最後のケースで:

>>> from collections import Counter 

>>> Counter("oloveleelo") 
Counter({'e': 3, 'l': 3, 'o': 3, 'v': 1}) 

ので'e''l''o'が同じkeyを持っているので、彼らが最初にやったように、彼らが表示されます。"oloeleelo"、その後、ちょうどその文字のみが来ます別のカウント:'v'があります。

あなただけCounter.most_commonの結果平らに、あなたもsortedを必要としない(それらは文字でグループ化されているだけのこと)と等しい数の多い要素の順序を気にしない場合:私は思う

>>> ''.join([item for item, cnt in Counter("oloveleelo").most_common() for _ in range(cnt)]) 
'llleeeooov' 
>>> ''.join([item for item, cnt in Counter("loveleel").most_common() for _ in range(cnt)]) 
'eeelllov' 
>>> ''.join([item for item, cnt in Counter("loveleee").most_common() for _ in range(cnt)]) 
'eeeellov' 
関連する問題