// Path: src/main/java/org/xm/tokenizer/Word.java
// public class Word implements Comparable {
//     // 词名
//     private String name;
//     // 词性
//     private String pos;
//     // 权重，用于词向量分析
//     private Float weight;
//     private int frequency;
// 
//     public Word(String name) {
//         this.name = name;
//     }
// 
//     public Word(String name, String pos) {
//         this.name = name;
//         this.pos = pos;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getPos() {
//         return pos;
//     }
// 
//     public void setPos(String pos) {
//         this.pos = pos;
//     }
// 
//     public Float getWeight() {
//         return weight;
//     }
// 
//     public void setWeight(Float weight) {
//         this.weight = weight;
//     }
// 
//     public int getFrequency() {
//         return frequency;
//     }
// 
//     public void setFrequency(int frequency) {
//         this.frequency = frequency;
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hashCode(this.name);
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (obj == null) {
//             return false;
//         }
//         if (getClass() != obj.getClass()) {
//             return false;
//         }
//         final Word other = (Word) obj;
//         return Objects.equals(this.name, other.name);
//     }
// 
//     public String toString(String split) {
//         if (HanLP.Config.ShowTermNature)
//             return name + split + pos;
//         return name;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder str = new StringBuilder();
//         if (name != null) {
//             str.append(name);
//         }
//         if (pos != null) {
//             str.append("/").append(pos);
//         }
//         if (frequency > 0) {
//             str.append("/").append(frequency);
//         }
//         return str.toString();
//     }
// 
//     @Override
//     public int compareTo(Object o) {
//         if (this == o) {
//             return 0;
//         }
//         if (this.name == null) {
//             return -1;
//         }
//         if (o == null) {
//             return 1;
//         }
//         if (!(o instanceof Word)) {
//             return 1;
//         }
//         String t = ((Word) o).getName();
//         if (t == null) {
//             return 1;
//         }
//         return this.name.compareTo(t);
//     }
// }


import org.xm.tokenizer.Word;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
/**
 * APDPlat - Application Product Development Platform
 * Copyright (c) 2013, 杨尚川, yang-shangchuan@qq.com
 * <p>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * <p>
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * <p>
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.xm.similarity.text;




/**
 * 文本相似度计算
 * 判定方式：Jaccard相似性系数（Jaccard similarity coefficient） ，通过计算两个集合交集的大小除以并集的大小来评估他们的相似度
 * 算法步骤描述：
 * 1、分词
 * 2、求交集（去重），计算交集的不重复词的个数 intersectionSize
 * 3、求并集（去重），计算并集的不重复词的个数 unionSize
 * 4、2中的值除以3中的值 intersectionSize/(double)unionSize
 * 完整计算公式：
 * double score = intersectionSize/(double)unionSize;
 * @author 杨尚川
 */
public class JaccardTextSimilarity extends TextSimilarity {
    /**
     * 判定相似度的方式：Jaccard相似性系数
     * @param words1 词列表1
     * @param words2 词列表2
     * @return 相似度分值
     */
    @Override
// Path: src/main/java/org/xm/tokenizer/Word.java
// public class Word implements Comparable {
//     // 词名
//     private String name;
//     // 词性
//     private String pos;
//     // 权重，用于词向量分析
//     private Float weight;
//     private int frequency;
// 
//     public Word(String name) {
//         this.name = name;
//     }
// 
//     public Word(String name, String pos) {
//         this.name = name;
//         this.pos = pos;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getPos() {
//         return pos;
//     }
// 
//     public void setPos(String pos) {
//         this.pos = pos;
//     }
// 
//     public Float getWeight() {
//         return weight;
//     }
// 
//     public void setWeight(Float weight) {
//         this.weight = weight;
//     }
// 
//     public int getFrequency() {
//         return frequency;
//     }
// 
//     public void setFrequency(int frequency) {
//         this.frequency = frequency;
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hashCode(this.name);
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (obj == null) {
//             return false;
//         }
//         if (getClass() != obj.getClass()) {
//             return false;
//         }
//         final Word other = (Word) obj;
//         return Objects.equals(this.name, other.name);
//     }
// 
//     public String toString(String split) {
//         if (HanLP.Config.ShowTermNature)
//             return name + split + pos;
//         return name;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder str = new StringBuilder();
//         if (name != null) {
//             str.append(name);
//         }
//         if (pos != null) {
//             str.append("/").append(pos);
//         }
//         if (frequency > 0) {
//             str.append("/").append(frequency);
//         }
//         return str.toString();
//     }
// 
//     @Override
//     public int compareTo(Object o) {
//         if (this == o) {
//             return 0;
//         }
//         if (this.name == null) {
//             return -1;
//         }
//         if (o == null) {
//             return 1;
//         }
//         if (!(o instanceof Word)) {
//             return 1;
//         }
//         String t = ((Word) o).getName();
//         if (t == null) {
//             return 1;
//         }
//         return this.name.compareTo(t);
//     }
// }


// Path: src/main/java/org/xm/similarity/text/JaccardTextSimilarity.java
import org.xm.tokenizer.Word;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

/**
 * APDPlat - Application Product Development Platform
 * Copyright (c) 2013, 杨尚川, yang-shangchuan@qq.com
 * <p>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * <p>
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * <p>
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.xm.similarity.text;




/**
 * 文本相似度计算
 * 判定方式：Jaccard相似性系数（Jaccard similarity coefficient） ，通过计算两个集合交集的大小除以并集的大小来评估他们的相似度
 * 算法步骤描述：
 * 1、分词
 * 2、求交集（去重），计算交集的不重复词的个数 intersectionSize
 * 3、求并集（去重），计算并集的不重复词的个数 unionSize
 * 4、2中的值除以3中的值 intersectionSize/(double)unionSize
 * 完整计算公式：
 * double score = intersectionSize/(double)unionSize;
 * @author 杨尚川
 */
public class JaccardTextSimilarity extends TextSimilarity {
    /**
     * 判定相似度的方式：Jaccard相似性系数
     * @param words1 词列表1
     * @param words2 词列表2
     * @return 相似度分值
     */
    @Override
    protected double getSimilarityImpl(List<Word> words1, List<Word> words2) {