Webページ消重アルゴリズム(java)


爬虫類の過程で、私たちはよくテーマの内容が同じページに遭遇します.例えば、ページを転載するなどです.タイトルが違うので、内容が微妙にずれているので、私たちの爬虫類は2つのページが違うと勘違いするかもしれません.この時、私たちはウェブページの内容をフィルタリングしなければなりません.ほとんどの消重技術は、ドキュメントごとに指紋のセット(fingerprint)を計算し、2つのドキュメントが一定数の同じ指紋を持っている場合、この2つのドキュメントの内容の重複性が高いと考えられ、すなわち、両方がコンテンツの転載であると考えられる基本思想に基づいている.(具体的な詳細は検索エンジン-原理、技術とシステムの本で詳しく紹介されています).
 
本の中のアルゴリズムの説明に基づいて、簡単に1つ書いて、ホームページの重いjavaコードを消して、コードのノートをします.
以下はアルゴリズムの主な部分である:具体的なアルゴリズムは、検索エンジン-原理、技術とシステムの本で詳しく紹介されている.
 
public class FileSimCal {

	private static final int N = 10;//         
	
	public FileSimCal() {
		
	}
	
	/**
	 *    n            
	 * 
	 * @param filepath
	 * @return Map<String, Integer>
	 */
	public Map<String, Integer> getTerms(String filepath) {
		FileReader fr = null;

		Map<String, Integer> map = new HashMap<String, Integer>();

		try {
			fr = new FileReader(filepath);
			IKSegmentation iks = new IKSegmentation(fr, true);
			Lexeme lexeme = null;
			while ((lexeme = iks.next()) != null) {
				String term = lexeme.getLexemeText();
				if (map.containsKey(term)) {
					int count = map.get(term) + 1;
					map.put(term, count);
				} else {
					map.put(term, 1);
				}
			}

			return map;

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}

		return null;
	}

	/**
	 *       ,  10 
	 * 
	 * @param words_T
	 * @return
	 */
	public String[] topTen(Map<String, Integer> words_T) {
		PriorityQueue<Entry<String, Integer>> queue = new PriorityQueue<Entry<String, Integer>>(1000, new Comparator<Entry<String, Integer>>() {
			public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
				if (o1.getValue() > o2.getValue()) {
					return -1;
				}

				if (o1.getValue() < o2.getValue()) {
					return 1;
				}

				return 0;
			};
		});

		String[] words = new String[N];
		Iterator<Entry<String, Integer>> it = words_T.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, Integer> entry = it.next();
			queue.add(entry);
			
		}
		
		int i = 0;
		while(!queue.isEmpty()) {
			Entry<String, Integer> entry = queue.poll();
			
			if(entry.getKey().length() < 2) {//      ,     ,  string         2
				continue;
			}
			
			words[i] = entry.getKey();
			i++;
			
			if(i == N) {//           
				break;
			}
		}
		
		return words;
	}
	
	/**
	 *      10      
	 * @param tenFrontWords
	 * @return
	 */
	public String concatenate(String[] tenFrontWords) {
		int i = 0;
		
		if(tenFrontWords.length < N) {
			return null;
		}
		
		StringBuilder sb = new StringBuilder();
		while (i < N) {
			System.out.print(tenFrontWords[i] + " ");
			sb.append(tenFrontWords[i]);
			i++;
		}
		
		System.out.println();
		if(sb != null && sb.length() > 0) {
			return sb.toString();
		}
		
		return null;
	}

	/**
	 *         md5 
	 * @param words
	 * @return
	 */
	public String md5(String words) {
		MessageDigest digest = null;
		StringBuffer sb = new StringBuffer();

		try {
			digest = MessageDigest.getInstance("MD5");
			digest.update(words.getBytes(), 0, words.length());

			byte[] tmp = digest.digest();
			BigInteger bigint = new BigInteger(1, tmp);
			sb.append(String.format("%1$016X", bigint));

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		return sb.toString();
	}

	/**
	 *   md5      
	 * @param p1
	 * @param p2
	 * @return
	 */
	public boolean mirror(String p1, String p2) {
		String p1_md5 = md5(p1).trim();
		String p2_md5 = md5(p2).trim();
		
		if(p1_md5.equals(p2_md5)) {
			return true;
		}
		
		return false;
	}
	
	public static void main(String[] args) {
		
		FileSimCal cal = new FileSimCal();
		PingYinCompare pingYinCompare = new PingYinCompare();
		
		
		//        
		Map<String, Integer> fwmap = cal.getTerms("./txt/fzfenghuang.txt");
		Map<String, Integer> qqmap = cal.getTerms("./txt/fzqq.txt");
		
		//    
		String[] topTenwords_fw = cal.topTen(fwmap);
		String[] topTenwords_qq = cal.topTen(qqmap);
		
		try {
			String[] pinyinarr_fw = pingYinCompare.pinYinArr(topTenwords_fw);
			String[] pinyinarr_qq = pingYinCompare.pinYinArr(topTenwords_qq);
			
			
			//        ,        
			pingYinCompare.quickSort(pinyinarr_fw, 0, pinyinarr_fw.length - 1, topTenwords_fw);
			pingYinCompare.quickSort(pinyinarr_qq, 0, pinyinarr_qq.length - 1, topTenwords_qq);
			
			//        
			String con_fw = cal.concatenate(topTenwords_fw);
			String con_qq = cal.concatenate(topTenwords_qq);
			
			//               
			if(cal.mirror(con_fw, con_qq)) {
				System.out.println("fzfenghuang.txt fzqq.txt       !");
			} else {
				System.out.println("fzfenghuang.txt fzqq.txt        !");
			}
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

ピンインの識別と並べ替えの比較:
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

public class PingYinCompare implements Comparator<String> {
	
	//        
	private HanyuPinyinOutputFormat format;
	
	public PingYinCompare() {
		this.format = new HanyuPinyinOutputFormat();
		format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		format.setVCharType(HanyuPinyinVCharType.WITH_V);
	}
	
	/**
	 *           
	 */
	public int compare(String o1, String o2) {
		return Collator.getInstance(Locale.ENGLISH).compare(o1, o2);
	}

	/**
	 *          
	 * @param src
	 * @return
	 * @throws BadHanyuPinyinOutputFormatCombination
	 */
	public String str2PingYin(String src) throws BadHanyuPinyinOutputFormatCombination {
		char[] chararr = src.toCharArray();
		StringBuffer sb = new StringBuffer();
		for(char c : chararr) {
			String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(c, this.format);
			sb.append(pinyin[0]);
		}
		return sb.toString();
	}
	
	/**
	 *     
	 * 
	 * @param arr 
	 * 			       
	 * @param left 
	 * 			        
	 * @param right 
	 * 			         
	 * @param src 
	 * 			      
	 */
	public void quickSort(String[] arr, int left, int right, String[] src) {
		String middle, tmp, tmp2;
		int i = left;
		int j = right;

		middle = arr[(left + right) / 2];
		
		do {
			while ((compare(arr[i], middle) < 0) && i < right) {//    middle   
				i++;
			}
			
			while ((compare(arr[j], middle) > 0) && j > left) {//    middle   
				j--;
			}

			if (i <= j) {//                ,      
				tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = tmp;
				
				//      
				tmp2 = src[i];
				src[i] = src[j];
				src[j] = tmp2;
				
				i++;// i    
				j--;// j    
			}
			
		} while (i < j);

		if (left < j) {
			quickSort(arr, left, j, src);
		}

		if (right > i) {
			quickSort(arr, i, right, src);
		}
	}
	
	/**
	 *       ,       
	 * @param src
	 * @return
	 * @throws BadHanyuPinyinOutputFormatCombination 
	 */
	public String[] pinYinArr(String[] src) throws BadHanyuPinyinOutputFormatCombination {
		if(src.length <= 0) {
			return null;
		}
		
		String[] temp = new String[src.length];
		for(int i = 0; i < temp.length; i++) {
			temp[i] = str2PingYin(src[i]);
		}
		
		return temp;
	}
	
	public static void main(String[] args) {
		PingYinCompare compare = new PingYinCompare();
		
		try {
			String p1 = compare.str2PingYin("     ");
			String p2 = compare.str2PingYin("     ");
			
			
			System.out.println(p1);
			System.out.println(p2);
			System.out.println(compare.compare(p2, p1));
			
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
 
参考文献:
Java環境に適した中国語の迅速なソートとあいまいな検索方法--劉煥煥陸鋒、趙雲山
 
添付ファイルは3つの転載した文章です.