找到一個單詞的所有相似單詞

相似單詞爲 只差一位字母的單詞,練習Map容器

package chapter4;

import java.util.*;
import java.util.Map.Entry;

/*
 * 說明:找到一個單詞的所有相似單詞 例如: wine 和 dine wind 和wing 只有一個字母不同
 */
public class TreeMapTest {

	/*
	 * 判斷2個單詞是否指差一個字母
	 */
	public static boolean oneCharOff(String s1, String s2) {
		if (s1.length() != s2.length())
			return false;
		int diff = 0;
		for (int i = 0; i < s1.length() - 1; i++) {
			if (s1.charAt(i) != s2.charAt(i))
				diff++;
			if (diff > 1)
				return false;
		}

		return diff == 1;
	}

	/*
	 * 打印方法
	 */
	public static void print(Map<String, List<String>> map) {
		for (Map.Entry<String, List<String>> entry : map.entrySet()) {
			List<String> words = entry.getValue();
			System.out.print(entry.getKey() + ":");
			for (int i = 0; i < words.size(); i++) {
				System.out.print(words.get(i) + " ");
			}
			System.out.println();
		}
	}

	/**
	 * 方法名:computeWords 說明:方法1
	 */
	public static Map<String, List<String>> computeWords1(List<String> words) {

		Map<String, List<String>> map = new TreeMap<String, List<String>>();
		String[] word = new String[words.size()];
		words.toArray(word);
		for (int i = 0; i < word.length; i++) {
			for (int j = i + 1; j < word.length; j++) {
				if (oneCharOff(word[i], word[j])) {
					update(map, word[i], word[j]);// 互爲相似單詞
					update(map, word[j], word[i]);
				}
			}
		}

		return map;
	}

	/**
	 * 方法名:update 說明:更新
	 */
	private static <KeyType> void update(Map<KeyType, List<String>> map,
			KeyType key, String s) {
		List<String> words = map.get(key);
		if (words == null) {
			words = new ArrayList<String>();
			map.put(key, words);
		}
		words.add(s);
	}

	/**
	 * 方法名:groupByLength 說明:先將給的單詞按照長度分組
	 */
	private static Map<Integer, List<String>> groupByLength(List<String> words) {
		Map<Integer, List<String>> map = new TreeMap<Integer, List<String>>();
		for (String s : words)
			update(map, s.length(), s);
		return map;
	}

	/**
	 * 方法名:computeWord 說明:方法2
	 */
	public static Map<String, List<String>> computeWords2(List<String> words) {

		Map<String, List<String>> map = new TreeMap<String, List<String>>();

		for (Entry<Integer, List<String>> entry : groupByLength(words)
				.entrySet()) {
			String[] word = new String[entry.getValue().size()];
			entry.getValue().toArray(word);
			for (int i = 0; i < word.length; i++) {
				for (int j = i + 1; j < word.length; j++) {
					if (oneCharOff(word[i], word[j])) {
						update(map, word[i], word[j]);// 互爲相似單詞
						update(map, word[j], word[i]);
					}
				}
			}
		}
		return map;

	}

	/**
	 * 方法名:computeWords3 
	 * 說明:該方法效率最高。首先也是按照長度分組,分組完了之後,對每組分別做以下操作:
	 * 1:從頭到尾分別去掉每個單詞的一位字母。將剩下的作爲一個鍵,該單詞作爲值 放到新建的
	 * map<String,List<String>>reToWord裏
	 * 2:遍歷reToWord,找到size>=2的,(因爲只有>=2的 才代表含有相似的)例如wine和wane 當去掉第2位
	 * 時,首先wine會進List,wane匹配到了wne也會進去,所以是2個
	 */
	public static Map<String, List<String>> computeWords3(List<String> words) {

		Map<String, List<String>> adjWords = new TreeMap<String, List<String>>();
		Map<Integer, List<String>> wordsByLength = new TreeMap<Integer, List<String>>();
		for (String w : words)
			update(wordsByLength, w.length(), w);

		for (Map.Entry<Integer, List<String>> entry : wordsByLength.entrySet()) {
			List<String> groupsWords = entry.getValue();
			int groupNum = entry.getKey();
			for (int i = 0; i < groupNum; i++) {
				Map<String, List<String>> repToWord = new TreeMap<String, List<String>>();
				for (String str : groupsWords) {
					String rep = str.substring(0, i) + str.substring(i + 1);
					update(repToWord, rep, str);
				}
				for (List<String> wordClique : repToWord.values())
					if (wordClique.size() >= 2)
						for (String s1 : wordClique)
							for (String s2 : wordClique)
								if (s1 != s2)
									update(adjWords, s1, s2);
			}
		}
		return adjWords;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<String> list = new ArrayList<String>();
		list.add("wane");
		list.add("wine");
		list.add("aine");
		list.add("dine");
		list.add("anew");
		list.add("kine");
		list.add("qine");
		list.add("eine");
		list.add("rine");

		print(computeWords1(list));
		System.out.println();
		print(computeWords2(list));
		System.out.println();
		print(computeWords3(list));
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章