clojurescript - 如何在不使用任何内置函数的情况下用另一个子字符串替换主输入字符串中的子字符串?

标签 clojurescript

我在网上搜索的每个函数都利用任何一个内置函数,如 find()、replace().etc 。我在学术书籍、图书馆和互联网上进行了研究,但找不到解决方案。你们中的任何人都可以提供一种在不使用任何内置函数的情况下实现上述功能的算法吗?

最佳答案

好吧,让我们先尝试解决一些更简单的问题,然后逐步解决字符串替换问题。首先,我们如何判断两个字符串相等?相当简单,对吧?如果字符串长度相同,并且相同字符的顺序相同,则它们相等:

(defn str-eq? [s1 s2]
  (and (= (count s1) (count s2))
       (every? identity
               (map = s1 s2))))

好吧,让我们尝试检查一个字符串是否有其他字符串作为前缀。事实证明,这是一个几乎相同的解决方案,我们只是放宽了两个字符串长度相同的要求:

(defn str-prefix? [s prefix]
  (and (>= (count s) (count prefix))
       (every? identity
               (map = s prefix))))

现在,让我们开始思考如何找到某个字符串 s 中所有出现的某个字符串 s1。好吧,如果我们将 s 的所有后缀按照从最长到最短的顺序排列,我们可以通过检查哪些后缀 s1 是以下前缀来确定 s1 出现在 s 中的位置:

(defn str-suffixes [s]
  (->> s
       (iterate next)
       (take (inc (count s))) ;; make sure we include the empty string
       (map #(apply clojure.core/str %))))

(defn str-find [s s1]
  (->> (str-suffixes s)
       (map (fn [index suffix] 
              (if (str-prefix? suffix s1) 
                index 
                nil))
            (iterate inc 0))
       (filter identity)))

最后,是时候进行字符串替换了。我们将从简单的情况开始,其中字符串 s1 在字符串 s 的索引处最多出现一次。只需将索引之前的所有内容与替换字符串 s2 以及 s 中出现 s1 之后的所有内容连接起来即可:

(defn str-replace [s s1 s2]
  (reduce (fn [s index]
            (apply clojure.core/str 
                   (concat (take index s)
                           s2
                           (drop (+ index (count s1)) s))))
          s
          (str-find s s1)))

如果s1在s中出现多次,你会发现这不起作用。这是因为 str-find 按升序给出结果。每次进行字符串替换时,都会使字符串中后面的索引失效。为了解决这个问题,我们只需从最大到最小处理每个索引:

(defn str-replace [s s1 s2]
  (reduce (fn [s index]
            (apply clojure.core/str 
                   (concat (take index s)
                           s2
                           (drop (+ index (count s1)) s))))
          s
          (sort > (str-find s s1))))

它正在发挥作用:

(str-replace "foobar" "foo" "baz")
=> "bazbar"
(str-replace "foobar" "bar" "baz")
=> "foobaz"
(str-replace "foobarbarfoo" "bar" "bazz")
=> "foobazzbazzfoo"
(str-replace "foobar" "z" "baz")
=> "foobar"

在解决此类问题时,思考还有哪些其他类似的操作以及它们与您要实现的操作之间的关系会有所帮助。如果您有任何疑问,请告诉我。

关于clojurescript - 如何在不使用任何内置函数的情况下用另一个子字符串替换主输入字符串中的子字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22333706/

相关文章:

clojure - 什么时候在 Clojure 宏中使用 ~'some-symbol?

javascript - 在使用 lein-cljsbuild 构建的 ClojureScript 中使用纯 .js 文件(Google Closure'd)

clojurescript - d3 JavaScript 到 ClojureScript 的翻译

clojure - 如何为试剂组件编写装饰器

clojure - 如何从本地存储中提取整数并使用 clojurescript 强制转换为整数

clojurescript - 无法在渲染阶段之外操作光标

clojure - 当结账依赖项发生变化时,如何让Figwheel重新加载网站?

clojure - ClojureScript 中函数调用结果的方法定义

clojure - 如何针对 LightTable 中的 HTML 页面进行交互式动态开发?

clojurescript - 在 clojurescript/试剂/reagi 中跟踪鼠标?