Clojure 使用recur时返回else值
我是Clojure的新手,我会尽力忘记我以前使用更多过程语言(java、ruby、swift)的所有经验,接受Clojure的本来面目。我真的很享受它让我有不同想法的方式——然而,我遇到了一个我似乎无法理解的模式。最简单的说明方法是使用一些代码:Clojure 使用recur时返回else值,clojure,Clojure,我是Clojure的新手,我会尽力忘记我以前使用更多过程语言(java、ruby、swift)的所有经验,接受Clojure的本来面目。我真的很享受它让我有不同想法的方式——然而,我遇到了一个我似乎无法理解的模式。最简单的说明方法是使用一些代码: (defn char-to-int [c] (Integer/valueOf (str c))) (defn digits-dont-decrease? [str] (let [digits (map char-to-int (seq str))
(defn char-to-int [c] (Integer/valueOf (str c)))
(defn digits-dont-decrease? [str]
(let [digits (map char-to-int (seq str)) i 0]
(when (< i 5)
(if (> (nth digits i) (nth digits (+ i 1)))
false
(recur (inc i))))))
(def result (digits-dont-decrease? "112233"))
(if (= true result)
(println "fit rules")
(println "doesn't fit rules"))
我该怎么想呢?我认为我过去的训练妨碍了我的思维。你可以使用
循环和重复。
假设您需要以下输入v/s输出-
- “543221”=>错误
- “54321”=>错误
- “12345”=>正确
- “123345”=>正确
下面的函数可以帮助您
;; Assuming char-to-int is defined by you before as per the question
(defn digits-dont-decrease?
[strng]
(let [digits (map char-to-int (seq strng))]
(loop [;;the bindings in loop act as initial state
decreases true
i (- (count digits) 2)]
(let [decreases (and decreases (>= (nth digits (+ i 1)) (nth digits i)))]
(if (or (< i 1) (not decreases))
decreases
(recur decreases (dec i)))))))
;;假设您之前根据问题定义了char到int
(定义数字不减少?
[strng]
(let[数字(将字符映射为int(seq strng))]
(循环[;;循环中的绑定充当初始状态
减少真实值
i(-(计数位数)2)]
(设[减少(和减少(>=(第n位(+i 1))(第n位i)))]
(如果(或(
这适用于任何长度的数字字符串
希望这有帮助。如果您正在寻找其他内容,请告诉我:)。您可以使用循环和重复。
假设您需要以下输入v/s输出-
- “543221”=>错误
- “54321”=>错误
- “12345”=>正确
- “123345”=>正确
下面的函数可以帮助您
;; Assuming char-to-int is defined by you before as per the question
(defn digits-dont-decrease?
[strng]
(let [digits (map char-to-int (seq strng))]
(loop [;;the bindings in loop act as initial state
decreases true
i (- (count digits) 2)]
(let [decreases (and decreases (>= (nth digits (+ i 1)) (nth digits i)))]
(if (or (< i 1) (not decreases))
decreases
(recur decreases (dec i)))))))
;;假设您之前根据问题定义了char到int
(定义数字不减少?
[strng]
(let[数字(将字符映射为int(seq strng))]
(循环[;;循环中的绑定充当初始状态
减少真实值
i(-(计数位数)2)]
(设[减少(和减少(>=(第n位(+i 1))(第n位i)))]
(如果(或(
这适用于任何长度的数字字符串
希望这有帮助。如果您正在寻找其他内容,请告诉我:)。(defn非递减?[str]
(每个?
身份
(地图
(fn[a b]
((定义非递减?[str]
(每个?
身份
(地图
(fn[a b]
(在本例中,您并不真正需要循环/重复。在本例中,您只需使用的内置特性。在本例中,您并不真正需要循环/重复。只需使用的内置特性,这并不是回答您的问题,但也显示了另一种选择。(应用<…)
整个串的方法对于小串来说非常优雅(它很急切),您可以使用每?
进行短路方法。例如:
user=>(定义序号[s](映射#(整数/parseInt(str%))s))
#'用户/序号:
user=>(every?(partial apply这不是回答您的问题,但也显示了另一种选择。虽然整个字符串上的(apply<…)
方法对于小字符串来说非常优雅(它很急切),但您可以使用every?
进行短路方法。例如:
user=>(定义序号[s](映射#(整数/parseInt(str%))s))
#'用户/序号:
用户=>(每?(部分应用您只需要
(apply>“0123456789”(mapcat#(重复1000%))(apply str)(def looong))
(龙伯爵)
10000
(时间(应用>9123456789)(mapcat#(重复1000%))(应用str)(def bad looong))
(巴德龙伯爵)
10000
(时间)你只需要
(apply>“0123456789”(mapcat#(重复1000%))(apply str)(def looong))
(龙伯爵)
10000
(时间(应用>9123456789)(mapcat#(重复1000%))(应用str)(def bad looong))
(巴德龙伯爵)
10000
(时间(应用您错过的recur
将调用该函数,将let
替换为loop
和(recur digits(inc i))
,(loop[digits(map…)i0](if(
扰流板:;)。因此,将字符串转换为数字,然后应用,感谢所有回答的人,他们都是很好的答案,教会了我一些东西。您错过了recur
将调用函数,将let
替换为loop
和(recur digits(inc i)),(loop[digits(map…)i 0](if(
SPOILER:;)。因此,将字符串转换为数字,然后应用感谢所有回答的人,他们都是很好的答案,教会了我一些东西。请稍微解释一下你的解决方案!这使理解你正在做的事情和原因变得越来越容易。请稍微解释一下你的解决方案!这使理解变得越来越容易D你正在做什么和为什么。<代码>应用非常好,但是只有小字符串-它是急切的。这也是相当多的代码框来显示<代码>(对不起,你是对的。我一定是在中间拖尾了)。<代码>应用非常好,但是只有小字符串-它是渴望的。这也是一个相当大的代码墙来显示<代码>(对不起,你是对的。我一定是在中间拖尾了)。
(defn non-decreasing? [str]
(every?
identity
(map
(fn [a b]
(<= (int a) (int b)))
(seq str)
(rest str))))
(defn non-decreasing-loop? [str]
(loop [a (seq str) b (rest str)]
(if-not (seq b)
true
(if (<= (int (first a)) (int (first b)))
(recur (rest a) (rest b))
false))))
(non-decreasing? "112334589")
(non-decreasing? "112324589")
(non-decreasing-loop? "112334589")
(non-decreasing-loop? "112324589")
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(def true-samples
["123"
"112233"
"13"])
(def false-samples
["10"
"12324"])
(defn char->int
[char-or-str]
(let [str-val (str char-or-str)] ; coerce any chars to len-1 strings
(assert (= 1 (count str-val)))
(Integer/parseInt str-val)))
(dotest
(is= 5 (char->int "5"))
(is= 5 (char->int \5))
(is= [1 2 3] (mapv char->int "123"))
; this shows what we are going for
(is (<= 1 1 2 2 3 3))
(isnt (<= 1 1 2 1 3 3))
;-----------------------------------------------------------------------------
; using built-in `<=` function
(doseq [true-samp true-samples]
(let [digit-vals (mapv char->int true-samp)]
(is (apply <= digit-vals))))
(doseq [false-samp false-samples]
(let [digit-vals (mapv char->int false-samp)]
(isnt (apply <= digit-vals))))
(defn increasing-equal-seq?
"Returns true iff sequence is non-decreasing"
[coll]
(when (< (count coll) 2)
(throw (ex-info "coll must have at least 2 vals" {:coll coll})))
(loop [prev (first coll)
remaining (rest coll)]
(if (empty? remaining)
true
(let [curr (first remaining)
prev-next curr
remaining-next (rest remaining)]
(if (<= prev curr)
(recur prev-next remaining-next)
false)))))
;-----------------------------------------------------------------------------
; using home-grown loop/recur
(doseq [true-samp true-samples]
(let [digit-vals (mapv char->int true-samp)]
(is (increasing-equal-seq? digit-vals))))
(doseq [false-samp false-samples]
(let [digit-vals (mapv char->int false-samp)]
(isnt (increasing-equal-seq? digit-vals))))
)
-------------------------------
Clojure 1.10.1 Java 13
-------------------------------
Testing tst.demo.core
Ran 2 tests containing 15 assertions.
0 failures, 0 errors.
Passed all tests
Finished at 23:36:17.096 (run time: 0.028s)