【问题标题】:Want more Clojure way to brute force string match想要更多 Clo​​jure 方法来暴力字符串匹配
【发布时间】:2014-09-29 21:20:07
【问题描述】:

我在 Clojure 中实现了一个蛮力字符串匹配算法。它可以正常工作,但我正在寻找的是如何使这段代码“更干净”并且更具可读性。请注意,我还必须让算法打印出它是如何进行字符比较的。我不知道所有需要注意的约定,我真的很想知道一些关于如何更好地编写 Clojure 的提示。

它的作用:它需要一段文本,并且对于它的每个索引(因为文本是字符串类型),将它与输入字符串匹配。如果匹配,我们将第二个字符与文本的下一个索引进行比较。用英语解释很多,但如果你运行程序,它会打印出它在做什么。

代码:

(defn underscores [n]
  (apply str (repeat n "_")))

(defn brute_force_string_match
  "Receives text as string type as its first argument,
  string in second argument, brute force matches the
  string to the text. Assumes text is longer than string."

  [text
   string]
  ;; for loop
  ;; i is 1 less than the amount of No matches you will get
  (loop [i 0
         j_and_matches [0 0]]
    ;;outer loop stops when i > n -m
    (if (and
             (<= i (- (count text) (count string)))
             (not= (j_and_matches 0) (count string)))
      ;; the "while loop"
      (do
        (println "")
        (print "\nPos = " i "\n"text"\n"
                   (str (underscores i) string))
        (recur
           (inc i)
           (loop [j 0
                  print_pos i
                  undscore_amt 0
                  matches (j_and_matches 1)]
             (if (and
                 (< j (count string))
                 (= (.charAt string j) (.charAt text (+ i j))))
               (do
                 (print "\n" (str (str (underscores print_pos)) "^   Match! "))
                 (recur (inc j)
                        (inc print_pos)
                        (inc undscore_amt)
                        (inc matches)))
               (do
                 (if (not= j (count string))
                   (print "\n" (str (str (underscores print_pos)) "^   No Match ")))
                 [j matches])))))

      (if (= (j_and_matches 0) (count string))
        (do (println "\n Pattern found at position " (dec i))
            (println "The number of comparisons: " (+ (j_and_matches 1) (dec i)))
            (dec i))
        -1))))

【问题讨论】:

  • 我没有完整的返工,但是一件小事:(print "\n" (str (str (underscores print_pos)) "^ Match! ")) 更好地表达为(print (str "\n" (underscores print_pos) "^ Match! "))

标签: string clojure match


【解决方案1】:

一方面,j 在您的外部循环中没有位置,它让i 遍历可能的匹配起点。 jstring 的本地索引,同时针对从 i 开始的 text 进行测试。

我会这样写:

(defn brute_force_string_match [text string]
  (let [last-start (- (count text) (count string))]
    (loop [i 0, matches []]
      (if (> i last-start)
        matches
        (let [match?
              (loop [j 0]
                (or (= j (count string))
                    (and (= (.charAt string j) (.charAt text (+ i j)))
                         (recur (inc j)))))]
          (recur (inc i) (if match? (conj matches i) matches)))))))

除了你的外循环中多余的j,我不知道你的和这个有很大的不同。

就风格而言,

  • 我已将复杂的内部loop 表达式绑定到本地match?。这保持了决赛 线路清晰。
  • 我使用andor 来简化该表达式中的条件。
  • 我已经将条件 (if match? ... ) 推到了 外复发。

注意

您可以使用get 而不是.charAt 来访问字符串中的字符。

【讨论】:

    猜你喜欢
    • 2017-05-04
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 2013-12-24
    • 2016-09-12
    相关资源
    最近更新 更多