查找给定单词的同义词



任务是编写一个可以决定两个单词是否为同义词的程序。

我有成对的同义词,例如:

[big large]  
[large huge]  
[small little] 

我们可以间接推导出同义关系:如果大是大的同义词,而大是巨大的同义词那么大就是巨大的同义语
成为同义词不取决于顺序,例如,如果big是big的同义词,那么big就是big的代名词。

程序必须回答给定的两个单词是否为同义词。

在我看来,这是逻辑编程的一个很好的候选者,例如使用clojure.core.logic.

a。如何将输入的同义词对声明为逻辑语句/约束
b。如何执行查询以查找给定单词的所有同义词?

或者我在刮胡子?解决这个问题的更简单的方法是什么?

一般来说,这看起来就像你对(图的(传递闭包感兴趣?

对于无向图("同义词不取决于顺序"(,这与连通组件有关(这里我们直接看到一些逻辑关系,因为2-SAT算法也利用连通组件(。

也可以参见:Algowiki

基本上:

  • 预处理时间:计算输入的传递闭包
  • 查询时间->同义词(a,b(:检查边(a,b(是否存在

或者不进行预处理:只需按需查找路径:

  • 查询时间->同义词(a,b(:检查a,b之间是否有路径
    • BFS/DFS

Clojure的数据结构使这类事情变得非常有趣。

这里的想法是,一组同义词本身是为该集中的所有单词共享的(作为同义词集(。

因此,我们生成了一个从单词到同义词集的映射:

(require '[clojure.set :as set])
(let [pairs [["big" "large"]
["large" "huge"]
["small" "little"]]
m (reduce (fn [eax [w1 w2]]
(let [s (set/union #{w1 w2} (get eax w1) (get eax w2))]
(merge eax (into {} (map #(vector % s) s)))))
{}
pairs)
syn? (fn [w1 w2] (boolean ((m w1 #{}) w2)))]
(println "big, large:" (syn? "big" "large"))
(println "big, huge:" (syn? "big" "huge"))
(println "huge, big:" (syn? "huge" "big"))
(println "big, small:" (syn? "big" "small"))
(println "code, large:" (syn? "code" "large")))

从这里开始的其他有趣的Clojure练习:

  1. 建筑m的时间和空间复杂性是多少?

  2. syn?的时间复杂度是多少

  3. 描述(然后通过测量确认(m内部正在进行的结构共享。

最新更新