【问题标题】:sorting according to a custom comparator根据自定义比较器排序
【发布时间】:2012-05-16 11:52:37
【问题描述】:

我有一张像这样的地图:

user> (frequencies "aaabccddddee")
{\a 3, \b 1, \c 2, \d 4, \e 2}

我想要一个函数,它可以根据每个字符在我作为参数传递的字符串中出现的顺序对键/值对进行排序。

类似这样的:

user> (somesort "defgcab" (frequencies "aaabccddddee"))
[[\d 4] [\e 2] [\c 2] [\a 3] [\b 1]]

(在上面的例子中,'f' 和 'g' 没有出现在地图中,因此它们被忽略了。保证字符串——在这个例子中是“defgcab”——应该包含每个地图中的字符/键)

生成的集合并不重要,只要它是排序的。

我已经尝试了几件事,但无法找到一种方法来完成这项工作。

【问题讨论】:

    标签: sorting map vector clojure


    【解决方案1】:

    我更喜欢使用sort-by 来执行排序逻辑,并为您的集合创建一个自定义比较器:

    (defn sorter [coll] (zipmap coll (range)))
    
    (sort-by (comp (sorter "defgcab") key) 
             (frequencies "aaabccddddee"))
    
    ;=> ([\d 4] [\e 2] [\c 2] [\a 3] [\b 1])
    

    编辑:这还有一个好处,即您可以根据需要将收藏保留为地图,尽管您需要做更多的工作:

    (defn map-sorter [coll]
      (let [order (zipmap coll (range))]
        (fn [a b]
          (compare (order a) (order b)))))
    
    (into (sorted-map-by (map-sorter "defgcab"))
          (frequencies "aaabccddddee"))
    
    ;=> {\d 4, \e 2, \c 2, \a 3, \b 1}
    

    【讨论】:

      【解决方案2】:
      (defn somesort [str st] 
          (filter (fn [[k v]] v ) (map (fn [c] [c (get st c)]) str)) )
      

      这是如何工作的:

      • 对该字符串中的每个字符使用“排序字符串”上的映射,从集合中获取对应的键值作为向量
      • 使用过滤器,过滤掉值为nil的元素

      【讨论】:

      • 哦,我明白了...谢谢。是不是意味着复杂度是O(n^2)?
      • @CedricMartin 复杂性取决于地图中的查找。如果映射很大,那么确保它是一个哈希映射,那么复杂度是线性的。
      【解决方案3】:

      Ankur 的解决方案用for 表示,可能更容易阅读:

      (defn somesort [str st] 
          (for [c str :let [v  (get st c)] :when v] [c v]))
      

      假设自定义排序字符串中的字符是唯一的。

      排序字符串被迭代一次,它的每个字符都在地图中查找。如果您确保传递给函数的映射是哈希映射,那么这是线性的。

      【讨论】:

        【解决方案4】:

        您也可以使用find,它返回[k v]map

        (let [fs (frequencies "abbccc")]
          (map #(find fs %) "defgcab")
        

        【讨论】:

        • 这不是为给定字母表中的每个字母调用frequencies吗?
        • @JeremyHeiler,是的。 Rafal 或 Ankur 解决方案更快
        • 确实非常低效!谢谢你们指出这一点。我太专注于“按值查找”,懒得把它包装在一个函数中。
        • 我做了一个小的调整,以便频率只计算一次。
        • 谢谢你,杰里米。这正是我想要的。我什至没有想到我可以编辑。
        猜你喜欢
        • 2013-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-29
        • 2021-03-23
        • 1970-01-01
        • 1970-01-01
        • 2019-11-22
        相关资源
        最近更新 更多