19

物事のリスト (ここでは単純にするために数字) があり、SortBy を使用してそれらを並べ替えるために使用したい関数があるとします。たとえば、次の例では、数字のリストを最後の桁で並べ替えます。

SortBy[{301, 201}, Mod[#,10]&]

そして、これらの数字のうち 2 つ (つまり、すべて) の最後の桁が同じであることに注目してください。したがって、それらをどの順序で返すかは問題ではありません。この場合、Mathematica は逆の順序でそれらを返します。元のリストでアイテムがどのように順序付けられているかを優先して、すべての関係が解消されるようにするにはどうすればよいですか?

(些細なことだとはわかっていますが、これは時々出てくる気がするので、StackOverflowで入手すると便利だと思いました。誰も私を打ち負かしなければ、思いついたものを答えとして投稿します.)

これをより検索しやすくするための試み: 乱れを最小限に抑えた並べ替え、スワップ数を最小限に抑えた並べ替え、カスタム タイブレーク、コストのかかるスワップによる並べ替え、安定した並べ替え

PS:これが安定ソートと呼ばれることを指摘してくれたNicholasに感謝します。それは私の舌の先にありました!ここに別のリンクがあります: リンク

4

4 に答える 4

24

いろいろ聞いてみると、納得のいく説明がありました。

簡単な答え:SortBy[list, {f}]安定した並べ替えが必要です。

長い答え:

SortBy[list, f]リストの各要素に f を適用することによって決定された順序でリストをソートし、 Sort で説明されている標準的な順序付けを使用して関係を解消します。(これは、 SortByのドキュメントに記載されている 2 番目の「詳細情報」ノートです。)

SortBy[list, {f, g}]各要素に g を適用することによって決定された順序を使用して同点を解消します。

SortBy[list, f]と同じであることに注意してくださいSortBy[list, {f, Identity}]

SortBy[list, {f}]タイブレークはありません(そして安定したソートを提供します)。これはあなたが望むものです:

In[13]:= SortBy[{19, 301, 201, 502, 501, 101, 300}, {Mod[#, 10] &}]

Out[13]= {300, 301, 201, 501, 101, 502, 19}

最後に、sakra のソリューションSortBy[list, {f, tie++ &}]は実質的に と同等SortBy[list, {f}]です。

于 2010-07-26T06:36:01.223 に答える
6

GatherBy はあなたが望むことを行いますか?

Flatten[GatherBy[{301, 201, 502, 501, 101}, Mod[#, 10] &]]
于 2010-07-22T11:11:39.220 に答える
5

SortBy追加の順序付け関数を使用して同点を解消するバリアントがあります。

SortBy[list,{f1, f2, ...}]

同点を数えることで、安定したソートを得ることができます。

Module[{tie = 0}, 
 SortBy[{19, 301, 201, 502, 501, 101, 300}, {Mod[#, 10] &, (tie++) &}]]

収量

{300, 301, 201, 501, 101, 502, 19}
于 2010-07-24T18:23:13.653 に答える
3

これはうまくいくようです:

stableSortBy[list_, f_] := 
  SortBy[MapIndexed[List, list], {f@First[#], Last[#]}&][[All,1]]

しかし今では、 rosettacodeがそれを行うためのはるかに優れた方法を提供していることがわかります。

stableSortBy[list_, f_] := list[[Ordering[f /@ list]]]

だから注文が鍵です!Mathematica のドキュメントでは、この重要な違いである並べ替えと順序付けについては言及されていないようです。

于 2010-07-21T23:23:56.533 に答える