3

以下の関数を見てください。因子のベクトルを渡し、ベクトル内の要素のいずれかが の因子であるかどうかをテストしたいと考えていxます。それ、どうやったら出来るの?

(defn multiple?
  "Takes a seq of factors, and returns true if x is multiple of any factor."
  ([x & factors] (for [e m] ))
  ([x factor] (= 0 (rem x factor))))
4

4 に答える 4

1

を使用するだけで解決できますsome

=> (defn multiple? [x factors]
 (some #(zero? (rem x %)) factors))
#'user/multiple?
=> (= true (multiple? 10 [3 4]))
false
=> (= true (multiple? 10 [3 4 5 6]))
true

some最初の要因で停止します。

于 2012-06-19T02:34:32.810 に答える
1

someとを試してみてくださいmap

(defn multiple? [x & factors]
  (some zero? (map #(rem x %) factors)))

また、すべてのテストが失敗した場合もsome返します。実際に返す必要がある場合は、そこに a を入れることができます。nilfalsetrue?

(defn multiple? [x & factors]
  (true? (some zero? (map #(rem x %) factors))))

some短絡し、map怠惰なのでmultiple?、一致が見つかるとすぐに停止することに注意してください。たとえば、次のコードは sequence に対してテストします1,2,3,4,...

=> (apply multiple? 10 (map inc (range)))
true

明らかに、この計算はmultiple?、シーケンス内のすべての数値に対してテストしない場合にのみ終了できます。

于 2012-06-19T02:11:23.567 に答える
0

明示的な末尾再帰を使用して、これを試してください。

(defn multiple? [x factors]
  "if any of the elements in the vector is a factor of x"
  (loop [factors factors]
        (cond (empty? factors) false
              (zero?  (rem x (first factors))) true
              :else   (recur (rest factors)))))

x上記のソリューションの利点は次のとおりです。ベクトル全体を反復処理することなく、ベクトル内の要素のいずれかが係数であるかどうかが検出されるとすぐに停止します。末尾再帰を使用することで、効率的で一定のスペースで実行されます。ブール値の結果を直接返します。を返す場合を考慮する必要はありませんnil。次のように使用します。

(multiple? 10 [3 4])
=> false

(multiple? 10 [3 4 5 6])
=> true

(このようなプロシージャを呼び出すために)ベクトルを明示的に渡す必要をなくしたい場合は、質問の場合と同じように、パラメータリストに(multiple? 10 3 4 5 6)aを追加するだけです。&

于 2012-06-19T02:14:47.017 に答える
0

よりクロージュリアンな方法は、より汎用的な関数を作成することです。真/偽の質問に答える代わりに、のすべての要素を返しますx。また、シーケンスは怠惰であるため、空であるかどうかを確認したい場合は、ほぼ同じくらい効率的です。

(defn factors [x & fs]
  (for [f fs :when (zero? (rem x f))] f))

(factors 5 2 3 4)
=> ()

(factors 6 2 3 4) 
=> (2 3)

次に、以下を使用するだけで元の質問に答えることができますempty?

(empty? (factors 5 2 3 4))
=> true

(empty? (factors 6 2 3 4))
=> false
于 2012-06-20T00:35:01.320 に答える