Android用Double Array Trie (双数组)实

作者: 小追兵 | 来源:发表于2016-04-12 11:46 被阅读423次

小追兵专栏

我们项目本想用这种方法做Android的搜索提示用,也就是,在搜索框中输入一个关键字,下面自动检索出和输入的关键词匹配的关键字,提示用户,用户可以方便的从下面的提示中选择出自己想要的关键字。提高用户体验。想要的效果如下图:
输入“你是你”,自动给出下面和“你是你”相关的选项。问题是我用双数组没有成功。只做到部分功能。完全不能实现如图的效果。下面以学习,总结为不目的,并提示大家少走弯路为出发点写的。

这里写图片描述

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

方法一 :

先上代码,后说效果。这里用的了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目录下面,然后读取出来。字典中的内容如下:

一举
一举一动
一举成名
一举成名天下知
万能
万能胶

输入:一举
查询结果:一举


输入:一举成名
查询结果:

一举 一举成名


输入:一举成名天下知
查询结果:

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


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

方法二:

同样的先上代码,后说效果。这里用的了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));
        }
    }

让我们看看结果吧:


输入:
查询结果:
一举 一举一动 一举成名 一举成名天下知


输入:一举成
查询结果:
一举成名 一举成名天下知


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

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

参考博客:

博客一

博客二

最后:有需要Shadowsock翻墙账号可以私聊。

相关文章

  • Android用Double Array Trie (双数组)实

    小追兵专栏 我们项目本想用这种方法做Android的搜索提示用,也就是,在搜索框中输入一个关键字,下面自动检索出和...

  • Double Array Trie 详细分享

    背景 - 文本关键词识别,想用一下- 网上看了一些文章,写的有认真的,但是总是缺定义,逻辑链条不完整====> 那...

  • Scala菜鸟的进阶之路之数组相关操作四

    多维数组 和Java一样,多维数组是通过数组的数组来实现的。举例来说,Double的二维数组类型为Array[A...

  • JS编码规范

    1.使用字面值创建对象和数组 2.用Array.from将类数组对象转换成数组 3.字符串用单引号' '而不是双引...

  • array处理函数

    创建数组array_fill 用给定的值填充数组array_fill_keys 只用指定的键和值填充数组array...

  • 数组的常用方法

    数组的常用方法 1. ES6: Array.of() Array.of() 方法创建一个具有可变数量参数的新数组实...

  • 第三章:数组

    在jvm中,scala的Array以java数组方式实现; Int, Double 或其他与java中基本类型对应...

  • JS将数组转成字符串

    1、String(array):输出数组的每个元素值,用逗号分隔;2、array.join("分隔符"):输出数组...

  • JS、JQ常用方法

    1. 数组 Array.slice() 方法可从已有的数组中返回选定的元素。 Array.concat() 方法用...

  • js数组--到底什么是数组 & a.forEach

    Array --数组 js中什么是数组?i. 用array构造出来的对象就是数组。ii.它与Object的区别是:...

网友评论

    本文标题:Android用Double Array Trie (双数组)实

    本文链接:https://www.haomeiwen.com/subject/wvtwlttx.html