android double 数组,Android用Double Array Trie (双数组)实现关键字的搜索

本文讲述了在Android应用中实现搜索提示功能遇到的问题,尝试使用双数组Trie算法从字典文件中匹配关键词,但发现该算法只能从头匹配,无法实现模糊或部分内容匹配。作者提供了两种实现方法,但都无法达到理想效果,最后建议考虑服务器端的搜索引擎解决方案。
摘要由CSDN通过智能技术生成

小追兵专栏

我们项目本想用这种方法做Android的搜索提示用,也就是,在搜索框中输入一个关键字,下面自动检索出和输入的关键词匹配的关键字,提示用户,用户可以方便的从下面的提示中选择出自己想要的关键字。提高用户体验。想要的效果如下图:

输入“你是你”,自动给出下面和“你是你”相关的选项。问题是我用双数组没有成功。只做到部分功能。完全不能实现如图的效果。下面以学习,总结为不目的,并提示大家少走弯路为出发点写的。

重点内容:

如果你想要这种效果,请别尝试了。不能实现,因为双数组只能实现如果第一条那种提示,也就是只能从头一个字开始匹配,不能实现,第二条,第三条那种模糊,或者部分能容的匹配。下面做详细举例说明。

方法一 :先上代码,后说效果。这里用的了github的一个项目darts-java,我们用项目作为工具类。private void searchFor(String key) {

String line;

List 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 integerList = dat.commonPrefixSearch(key);        for (int index : integerList) {

System.out.println(words.get(index));

}

}

从代码可以看出来,我们将一个字典文件small.dic放在了项目的assets目录下面,然后读取出来。字典中的内容如下:一举

一举一动

一举成名

一举成名天下知

万能

万能胶

输入:一举

查询结果:一举

输入:一举成名

查询结果:

一举 一举成名

输入:一举成名天下知

查询结果:

一举 一举成名 一举成名天下知

由此可见,不是我们想要的结果,这是输入关键词后,匹配字典。查询目的都反了。不符合放弃。本想自己改,可是发现要研究算法就够我耗费巨大的体力,所以放弃里自己修改的想法。

方法二:同样的先上代码,后说效果。这里用的了github的一个项目DoubleArrayTrie,我们用项目作为工具类。private void searchFor1(String key) {

ArrayList words = new ArrayList();        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 strings = dat.FindAllWords(key);        for (int i = 0; i 

System.out.println(strings.get(i));

}

}

让我们看看结果吧:

输入:一

查询结果:

一举 一举一动 一举成名 一举成名天下知

输入:一举成

查询结果:

一举成名 一举成名天下知

可见,这基本是我想要的效果了。可是这也只能是基本效果,不能作为我们的解决方案,因为当我们输入中间某个关键字,就会什么也搜不到,例如:天下,我们什么都查不到。所以就这能这样了。

字典文件只是一个举例,我们打算的是从数据库导出一个文件,这个文件格式还没有确定,不过被上面的技术否定了,就没有继续。如果你有好的方案,可以留言。可能大多数的搜索,是服务器端做的搜索引擎吧。时间原因,我们还没做引擎。

参考博客:

作者:小追兵

链接:https://www.jianshu.com/p/b3e23dbb07ef

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值