小追兵專欄
我們項目本想用這種方法做Android的搜索提示用,也就是,在搜索框中輸入一個關鍵字,下面自動檢索出和輸入的關鍵詞匹配的關鍵字,提示用戶,用戶可以方便的從下面的提示中選擇出自己想要的關鍵字。提高用戶體驗。想要的效果如下圖:
輸入“你是你”,自動給出下面和“你是你”相關的選項。問題是我用雙數組沒有成功。只做到部分功能。完全不能實現(xiàn)如圖的效果。下面以學習,總結為不目的,并提示大家少走彎路為出發(fā)點寫的。
重點內容:
如果你想要這種效果,請別嘗試了。不能實現(xiàn),因為雙數組只能實現(xiàn)如果第一條那種提示,也就是只能從頭一個字開始匹配,不能實現(xiàn),第二條,第三條那種模糊,或者部分能容的匹配。下面做詳細舉例說明。
方法一 :
先上代碼,后說效果。這里用的了github的一個項目darts-java,我們用項目作為工具類。
private void searchFor(String key) {
String line;
List<String> words = new ArrayList<>();
try {
//讀取assets目錄下的small.dic文件
InputStreamReader inputReader = new InputStreamReader(getResources().getAssets().open("small.dic"));
BufferedReader reader = new BufferedReader(inputReader);
while ((line = reader.readLine()) != null) {
words.add(line);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
DoubleArrayTrie dat = new DoubleArrayTrie();
System.out.println("是否錯誤: " + dat.build(words));
System.out.println(dat);
List<Integer> integerList = dat.commonPrefixSearch(key);
for (int index : integerList) {
System.out.println(words.get(index));
}
}
從代碼可以看出來,我們將一個字典文件small.dic放在了項目的assets目錄下面,然后讀取出來。字典中的內容如下:
一舉
一舉一動
一舉成名
一舉成名天下知
萬能
萬能膠
輸入:一舉
查詢結果:一舉
輸入:一舉成名
查詢結果:
一舉 一舉成名
輸入:一舉成名天下知
查詢結果:
一舉 一舉成名 一舉成名天下知
由此可見,不是我們想要的結果,這是輸入關鍵詞后,匹配字典。查詢目的都反了。不符合放棄。本想自己改,可是發(fā)現(xiàn)要研究算法就夠我耗費巨大的體力,所以放棄里自己修改的想法。
方法二:
同樣的先上代碼,后說效果。這里用的了github的一個項目DoubleArrayTrie,我們用項目作為工具類。
private void searchFor1(String key) {
ArrayList<String> words = new ArrayList<String>();
String line;
try {
//讀取assets目錄下的small.dic文件
InputStreamReader inputReader = new InputStreamReader(getResources().getAssets().open("small.dic"));
BufferedReader reader = new BufferedReader(inputReader);
while ((line = reader.readLine()) != null) {
words.add(line);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
DoubleArrayTrie1 dat = new DoubleArrayTrie1();
for (String word : words) {
try {
dat.Insert(word);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(dat.Base.length);
System.out.println(dat.Tail.length);
System.out.println(dat.Exists(key));
ArrayList<String> strings = dat.FindAllWords(key);
for (int i = 0; i < strings.size(); i++) {
System.out.println(strings.get(i));
}
}
讓我們看看結果吧:
輸入:一
查詢結果:
一舉 一舉一動 一舉成名 一舉成名天下知
輸入:一舉成
查詢結果:
一舉成名 一舉成名天下知
可見,這基本是我想要的效果了??墒沁@也只能是基本效果,不能作為我們的解決方案,因為當我們輸入中間某個關鍵字,就會什么也搜不到,例如:天下,我們什么都查不到。所以就這能這樣了。
字典文件只是一個舉例,我們打算的是從數據庫導出一個文件,這個文件格式還沒有確定,不過被上面的技術否定了,就沒有繼續(xù)。如果你有好的方案,可以留言。可能大多數的搜索,是服務器端做的搜索引擎吧。時間原因,我們還沒做引擎。
參考博客: