Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
clojure中的折叠散列函数_Clojure_Hash Function - Fatal编程技术网

clojure中的折叠散列函数

clojure中的折叠散列函数,clojure,hash-function,Clojure,Hash Function,折叠散列函数将其输入(在本例中为int)分解为p长度的段并添加这些部分。如果(非(=(mod input p)0)),即输入的长度不是p的倍数,则最后一段的长度可以是小于p的任意长度 以下是我目前的代码: (def firstX (fn [x item] (take x (str item)))) (def remX (fn [x item] (drop x (str item)))) (def divItemEq (fn [a digits] (co

折叠散列函数将其输入(在本例中为int)分解为p长度的段并添加这些部分。如果
(非(=(mod input p)0))
,即输入的长度不是p的倍数,则最后一段的长度可以是小于p的任意长度

以下是我目前的代码:

(def firstX
  (fn [x item]
    (take x (str item))))

(def remX
  (fn [x item]
    (drop x (str item))))

(def divItemEq
  (fn [a digits]
      (cond (> digits (count (str a))) (a)
            true (cons (list (firstX digits a)) (divItemEq (remX digits a) digits)))))

(def sumDigits
  (fn [x]
    (reduce + x)))

(def exItem1 76123451001214)
(print (sumDigits (divItemEq exItem1 3)))
此时,无限递归(堆栈溢出)发生,因为DiviItemEq中的递归条件从未满足。我试图修复此问题导致了各种类型/类型转换错误


关于如何改进
divItemEq

我不确定您不想使用哪些其他核心功能,但我提出了以下解决方案:

(defn chars->int [chars]
  (Integer/parseInt (apply str chars)))

(defn int-partition [n count]
  (loop [acc [] xs (str n)]
    (if (seq xs)
      (recur (conj acc (chars->int (take count xs))) (drop count xs))
      acc)))

(int-partition 76123451001214 3)
;; yields
[761 234 510 12 14]

(reduce + (int-partition 76123451001214 3))
;; yields
1531

请注意,此版本不是惰性的,可能不适用于大型输入。您可能希望使用修改它。

我不确定您不想使用哪些其他核心功能,但我提出了以下解决方案:

(defn chars->int [chars]
  (Integer/parseInt (apply str chars)))

(defn int-partition [n count]
  (loop [acc [] xs (str n)]
    (if (seq xs)
      (recur (conj acc (chars->int (take count xs))) (drop count xs))
      acc)))

(int-partition 76123451001214 3)
;; yields
[761 234 510 12 14]

(reduce + (int-partition 76123451001214 3))
;; yields
1531

请注意,此版本不是惰性的,可能不适用于大型输入。您可能希望使用修改它。

这里有很多地方需要改进,第一个是使用更惯用的
defn
而不是
(def name(fn
scheme。接下来是您的姓名,我发现您的姓名不太清楚。其他人已经为您指明了使用
分区的方向,我同意这一点,但在下面的解决方案中,我试图遵循您方法的精神

正如你自己发现的那样,将数字转换为数字序列是很有意义的,因为我们无论如何都需要序列运算。所以让我们从这个开始:

(defn decimal-digits [number]
  (letfn [(ddigits-helper [number result]
              (if (number > 0)
                  (recur (int (/ number 10)) (conj result (mod number 10)))
                  result))]
     (ddigits-helper number '())))
这种方法使用简单的数学来收集数字。它还显示了使用
recur
进行递归,并使用累加器(
result
参数)来收集中间结果

下面是两个初始函数,我们假设它们现在在数字列表上运行:

(defn new-part [number size]
  (take size number))

(defn rest-part [number size]
  (drop size number))
如前所述,您还可以使用
分区
处拆分

现在,您的主要功能可以如下所示:

(defn partition-number
        [number size]
        (let [digits (decimal-digits number)]
          (cond (> size (count digits)) digits
                true (cons (new-part digits size)
                           (partition-number 
                              (digits-to-decimal (rest-part digits size)) 
                              size)))))
这在风格上与您的方法非常接近,但表明我们需要将数字转换回数字,因为这正是
分区号
所期望的

(defn digits-to-decimal [digits]
  (let [powers-of-ten (iterate (partial * 10) 1)
        digits (reverse digits)]
    (reduce +
        (map-indexed (fn [position digit]
                         (* digit (nth powers-of-ten position)))
                     digits))))
但是,如果我们重新构造
分区号
以同时使用带有累加器的helper函数,我们还可以使用
recur
,这就是在clojure中避免递归调用时破坏堆栈的方法:

(defn partition-number
  [number size]
  (letfn [(partnumb-helper [digits size result]
               (cond (> size (count digits)) (conj result digits)
                     true (recur (rest-part digits size) 
                                 size
                                 (conj result (new-part digits size)))))]
     (partnumb-helper (decimal-digits number) size '[])))

请注意,这样我们也可以随时在数字和数字之间进行转换。

这里有很多地方需要改进,第一个是使用更惯用的
defn
而不是
(def name(fn
scheme。接下来是您的姓名,我发现您的姓名不太清楚。其他人已经为您指明了使用
分区的方向,我同意这一点,但在下面的解决方案中,我试图遵循您方法的精神

正如你自己发现的那样,将数字转换为数字序列是很有意义的,因为我们无论如何都需要序列运算。所以让我们从这个开始:

(defn decimal-digits [number]
  (letfn [(ddigits-helper [number result]
              (if (number > 0)
                  (recur (int (/ number 10)) (conj result (mod number 10)))
                  result))]
     (ddigits-helper number '())))
这种方法使用简单的数学来收集数字。它还显示了使用
recur
进行递归,并使用累加器(
result
参数)来收集中间结果

下面是两个初始函数,我们假设它们现在在数字列表上运行:

(defn new-part [number size]
  (take size number))

(defn rest-part [number size]
  (drop size number))
如前所述,您还可以使用
分区
处拆分

现在,您的主要功能可以如下所示:

(defn partition-number
        [number size]
        (let [digits (decimal-digits number)]
          (cond (> size (count digits)) digits
                true (cons (new-part digits size)
                           (partition-number 
                              (digits-to-decimal (rest-part digits size)) 
                              size)))))
这在风格上与您的方法非常接近,但表明我们需要将数字转换回数字,因为这正是
分区号
所期望的

(defn digits-to-decimal [digits]
  (let [powers-of-ten (iterate (partial * 10) 1)
        digits (reverse digits)]
    (reduce +
        (map-indexed (fn [position digit]
                         (* digit (nth powers-of-ten position)))
                     digits))))
但是,如果我们重新构造
分区号
以同时使用带有累加器的helper函数,我们还可以使用
recur
,这就是在clojure中避免递归调用时破坏堆栈的方法:

(defn partition-number
  [number size]
  (letfn [(partnumb-helper [digits size result]
               (cond (> size (count digits)) (conj result digits)
                     true (recur (rest-part digits size) 
                                 size
                                 (conj result (new-part digits size)))))]
     (partnumb-helper (decimal-digits number) size '[])))

请注意,这样我们也可以随时在数字和数字之间转换。

您已经解释了实际行为(
StackOverflowerError
);您可以给出预期/期望的行为吗?期望的行为:(diviteeq exItem1 3)计算为((761)(234)(510)(012)(14)),传递给sumDigits。该应用程序产生1531。旁注:我在第二次检查时更正了递归情况。我预计我的问题源于我对Clojure类型系统的初步理解。改用。我希望避免内置函数,但感谢
分区
@jmargolisvtI su的建议假设我的问题是将int输入转换为类似lat(原子列表)的东西,您已经解释了实际行为(
StackOverflowerError
);您能给出预期/期望的行为吗?期望的行为:(diviteeq exItem1 3)计算为((761)(234)(510)(012)(14)),传递给sumDigits。该应用程序产生1531。旁注:我在第二次检查时更正了递归情况。我预计我的问题源于我对Clojure类型系统的初步理解。改用。我希望避免内置函数,但感谢
分区
@jmargolisvtI su的建议我的问题是把int输入转换成lat(原子列表)之类的东西,回答得很好