// 注意:代码在模板里又删了一些无用代码和注释,若导致程序无法运行,请自行查找。没删之前代码经过测试可用。
// 写得有点粗糙没有优化,以后在优化吧,也欢迎同行指正!
// 空间和时间复杂度自己写吧
题目1:最小距离
有一个word list的txt文件,包含100M 个无序的单词,每行一个词;
单词: 词纯由英文字母组成,比如grass、tree、love、engineer
相近词: 相近词是原词或原词衍变,最多一个差异字母;如love的相近词可是 love、lova、loae、lave、aove等等任一个
两词的距离:txt文件中,两个词相隔多少行
函数输入:两个词 X 和 Y
函数输出:找到 X相近词 和 Y相近词 的最小距离;并注释写明其空间和时间复杂度
举例:
package algorithm;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
*
* @author lv
*
*/
public class WordList {
/**
* @param args
*/
public static void main(String[] args) {
try {
String fileUrl = "F:\\MyEclipse_Workspaces\\wordstest.txt";
long start = System.currentTimeMillis();
System.out.println(start);
HashMap<Integer,ArrayList<HashMap<String,Integer>>> map = getMinimumDistance("lova","geass",fileUrl);
for(Map.Entry<Integer,ArrayList<HashMap<String,Integer>>> entry : map.entrySet()){
int key = entry.getKey();
ArrayList<HashMap<String,Integer>> list = entry.getValue();
System.out.println("X相近词 和 Y相近词 的最小距离为: "+key);
for(HashMap<String,Integer> hmap : list){
System.out.println("X相近词行号 :"+hmap.get("x")+" Y相近词行号:" +hmap.get("y"));
}
}
long end = System.currentTimeMillis();
System.out.println(end);
System.out.println(end-start);
} catch(FileNotFoundException e) {
e.printStackTrace();
}
}
/**
*
* @param x
* @param y
* @param fileUrl
* @return 返回值为整型最小距离和该距离对应参数 x 和 y 的行号
* @throws FileNotFoundException
*/
public static HashMap<Integer, ArrayList<HashMap<String,Integer>>> getMinimumDistance(String x,String y,String fileUrl) throws FileNotFoundException {
Map<String,Integer> map = getContent(fileUrl);
ArrayList<Integer> xList = getRowNumbers(x,map);
ArrayList<Integer> yList = getRowNumbers(y,map);
ArrayList<Integer> list = new ArrayList<Integer>();
HashMap<Integer,ArrayList<HashMap<String,Integer>>> ma = newHashMap<Integer, ArrayList<HashMap<String,Integer>>>();
ArrayList<HashMap<String,Integer>> list2 = new ArrayList<HashMap<String,Integer>>();
HashMap<String,Integer> hmap = new HashMap<>();
int temp;
for(int i=0;i< xList.size();i++){
for(int j=0;j< yList.size();j++){
temp = Math.abs(xList.get(i)- yList.get(j));
if(hmap.size()== 0){
hmap.put("x",xList.get(i));
hmap.put("y",yList.get(j));
list2.add(hmap);
ma.put(temp,list2);
}else{
ArrayList<Integer> lis = new ArrayList<Integer>();
for(Entry<Integer,ArrayList<HashMap<String, Integer>>> k : ma.entrySet()){
lis.add(k.getKey());
}
int key =lis.get(0);
if(key ==temp){
HashMap<String,Integer>mp = new HashMap<String,Integer>();
mp.put("x",xList.get(i));
mp.put("y",yList.get(j));
list2.add(mp);
ma.put(temp, list2);
}elseif(key<temp){
continue;
}else{
list2.clear();
hmap.put("x",xList.get(i));
hmap.put("y",yList.get(j));
list2.add(hmap);
ma.put(temp, list2);
}
}
list.add(temp);
System.out.println("x : "+xList.get(i)+" y :"+yList.get(j)+" temp :"+temp);
}
}
Collections.sort(list);
int ke =list.get(0);
ArrayList<HashMap<String, Integer>> al = ma.get(ke);
ma.clear();
ma.put(ke, al);
return ma;
}
/**
*
* @param str 输入的单词
* @param map 文件数据
* @return 返回值是文件中所有该str单词相近词的行号的集合
*/
public static ArrayList<Integer> getRowNumbers(String str,Map<String,Integer>map){
ArrayList<Integer> rows = new ArrayList<Integer>();
if(str !=null && str != ""){
int strLeng = str.length();
for(Stringkey : map.keySet()){
int leng = key.length();
//先过滤一下位数相同的值减少循环次数
if(leng == strLeng){
int count = 0;
//比较str的近义词与entryValue
for(int i = 0; i < leng; i++){
if(str.charAt(i) == key.charAt(i))
++count;
}
if(count >= strLeng-1){
rows.add(map.get(key));
}
}
}
}
return rows;
}
/**
* 读取文件到HashMap (每行的单词及其行号对应Map的一个Key和Value)
* @param url 文件路径
* @return
* @throws FileNotFoundException
*/
public static HashMap<String,Integer> getContent(String url) throws FileNotFoundException{
File file = new File(url);
if(!file.exists())
throw new FileNotFoundException("未找到指定文件!");
HashMap<String, Integer> map = new HashMap<String,Integer>();
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = null;
BufferedReader br = null;
int fileSize = 1024*1024*50;//100M 具体根据经验确认,这里只是为了方便
String str = null;
int startLine = 1;
try {
isr = new InputStreamReader(fis,"utf-8");
br = new BufferedReader(isr,fileSize);
while((str =br.readLine()) != null){
//读入的字符串及其行号添加到Map对应的value和key
map.put(str,startLine++);
}
} catch(UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}finally{
try {
fis.close();
isr.close();
} catch(IOException e) {
e.printStackTrace();
}
}
return map;
}
}