3

次のリストに最大演算子を適用する必要があります

[Tier20 Tier10 Tier30]

そして、それは私を与える必要があります

Tier30

定義済みの順序付きリスト (低いものから高いものへ) は次のとおりです。

[Tier5 Tier10 Tier20 Tier30 Tier40 Tier50]

Clojureでこれを達成する最良の方法は何ですか?

4

4 に答える 4

6

最初に順序を定義します。

user> (def order '[Tier5 Tier10 Tier20 Tier30 Tier40 Tier50])
#'user/order

次に、を作成して並べ替えることができるものに順序をマップしますmap

user> (def order-map (zipmap order (range)))
{Tier50 5, Tier40 4, Tier30 3, Tier20 2, Tier10 1, Tier5 0}

必要なのが最大値/最小値だけである場合は、オーダー マップを使用して入力を減らします。

user> (reduce #(if (< (order-map %1) (order-map %2)) %1 %2) 
              '[Tier20 Tier10 Tier30])
Tier30


または、完全な順序付けが必要な場合は、並べ替え関数を使用します。これは、比較の前に入力を変換する機会を与えることを除いて、通常の並べ替え関数に似ています。

user> (sort-by (zipmap order (range)) '[Tier20 Tier10 Tier30])
(Tier10 Tier20 Tier30)

このマップを何度も変更する必要があり、毎回再ソートする必要がない場合は、データ構造を使用しsorted-set-byて入力を保存します。

于 2012-12-05T21:59:52.453 に答える
2

reduceを使用します。たとえば、リストLの最大値を見つけるには、次のようにします。

(reduce max L)

ここでの本当の問題は、投稿から完全に明確ではないため、層が文字列であるか、より複雑なオブジェクトであるかということです。どちらの方法でも、maxをラムダ式に置き換えて、次のように文字列の数値部分を引き出すことができます。

(reduce (fn [x y] ...) L)

ここで...は、データから数値部分を抽出する式になります。

于 2012-12-05T20:06:04.960 に答える
1

これが私が試したところです。レバレッジの主なポイントは、のインスタンスメソッド.indexOfですclojure.lang.Vector

user> (def x ['Tier5 'Tier10 'Tier20 'Tier30 'Tier40 'Tier50])
#'user/x
user> (index-of x 'Tier10)
; Evaluation aborted.
user> (.indexOf x 'Tier10)
1
user> (def y ['Tier20 'Tier10 'Tier30])
#'user/y
user> (reduce #(max %1 (.indexOf x %2)) y)
; Evaluation aborted.
user> (x (reduce #(max %1 (.indexOf x %2)) 0 y))
Tier30
user>

当然、これはO(n 2)です。これを大規模に行う場合は、TierNからその順序付けインデックスへのハッシュマップによってはるかに優れたサービスが提供されます。

于 2012-12-05T20:08:18.173 に答える
0

配列がの場合、java.lang.String相互運用性が少しあります。

user=> (def array ["Tier5" "Tier10" "Tier20" "Tier30" "Tier40" "Tier50"])
#'user/array
user=> (defn find-max [m] (reduce #(if (> (.compareTo %1 %2) -1) %1 %2) m))
#'user/find-max
user=> (find-max array)
"Tier50"
user=> (find-max "a")
\a

それらを実装させるだけではない場合Comparable、またはを作成し Comparatorます。

于 2012-12-05T20:31:47.623 に答える