0

我的具体问题与一个 Android 项目有关,但这不是一个具体的 android 问题。

我基本上只是想想出一种方法,我可以查询数据库并返回结果,而不是基于精确匹配,而是基于相似的术语,即使在字符串是否“包含”键入值的搜索范围之外。

例如,假设我有一个名为“大力水手的鲶鱼”的条目。假设有人输入了“P's CatSalmon”一词并正在寻找该条目。我想返回一个基本上显示“最相似”匹配的查询列表。

我承认我在数据库查询方面完全是新手,所以可能有现成的答案,我只是找不到(我确实看过)。我可以想到几种方法来做到这一点:

  1. 我可以分解搜索字符串并在实际条目的“包含”搜索中查找每个字符串的单独部分。例如,我可以拆分“P”“Cat”和“Salmon”搜索所有三个并执行一些其他代码来找出最佳结果是什么。但是,我真的不确定如何对其进行编码,以便程序可以选择最好的段。例如,如果不遍历所有可能性(这几乎肯定是不现实的),它如何知道挑选“猫”?

  2. 我可以让用户受苦一段时间,直到标签存在。我的意思是,一旦通过“正确”名称找到正确的条目,我可以让用户用关联名称对其进行标记,然后在以后用户的搜索中包含该单独的关联名称。

根据我目前的知识水平,我想不出比这更好的了。

在此先感谢您的帮助。

4

2 回答 2

1

我猜这是某种查找位置应用程序。所以让我们假设位置的数量很少,比如少于 200 个。

您将首先构建一个搜索,以查找用户在位置中键入的“单词”。在您的示例中,我们有“P's”和“CatSalmon”。“CatSalmon 不会匹配任何东西,“P's”也不会。

因此,您返回如下所示的内容:

Locations found for "P's CatSalmon"
-----------------------------------
No locations found.  Try using different search terms.

因此,我们的用户键入“P CatSalmon”。

因此,您返回所有以字母 P 开头的位置,然后返回包含字母 P 的位置。

像这样的东西:

Locations found for "P CatSalmon"
---------------------------------
Popeye's Catfish
Public library
Hope Restaurant
...

现在,这就是有趣的地方。

当用户选择一个位置时,您会记录搜索词和所选位置。

在您的示例中,用户将选择“大力水手的鲶鱼”。

所以稍后,您手动将此键值添加到同义词映射中。

Key        Value
---------  ----------
CatSalmon  Catfish

随着时间的推移,您的搜索会变得更好,因为您的用户将定义同义词。

所以,回顾一下。

  • 您搜索以单词开头的位置。

  • 您搜索包含单词的位置。

  • 您在同义词映射中查找同义词,然后使用同义词重复开始/包含过程。

  • 首先显示起始位置,然后包含位置。

最后,您在带有数据库的服务器上完成所有这些工作。您将排序的位置列表传递给手机。不要让手机完成所有工作。

于 2013-07-02T18:55:01.417 回答
0

这是我放在一起的东西,本质上是通过基于连续字符数的查询突出显示最接近的匹配项

公共类 SequenceMatches {

public static void main(String [] args)
{
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    String query = "P's SalmonCat ";

    map = addTermsToHashMap(map);// add terms to a hash map
    map = compareFirstCharacter(map, query);// compare the initial first character
    map= compareSequentialCharacters(map, query);// compare terms to query and add score based on the number of matches
    printResults(map);
}


    public static HashMap<String,Integer> addTermsToHashMap(HashMap<String,Integer> map){
    String term = "Popeye's CatFish";
    String otherTerm = "Popets CatSalmon";
    map.put(term,0);
    map.put(otherTerm,0);

    return map;
    } 

    public static HashMap<String,Integer> compareFirstCharacter(HashMap<String,Integer> map,String query){

        for(Map.Entry<String,Integer> e: map.entrySet())
        {
            String term = e.getKey();
            char [] termChar = term.toCharArray();
            char [] queryChar = query.toCharArray();

            if((queryChar[0]) == (termChar[0]))
            {
                int value = map.get(term);
                map.put(term,++value);
            }
        }

        return map;
    }

    public static HashMap<String,Integer> compareSequentialCharacters(HashMap<String,Integer> map,String query){
        for(Map.Entry<String,Integer> e: map.entrySet())
        {
            String term = e.getKey();
            char [] termChar = term.toCharArray();
            char [] queryChar = query.toCharArray();



            for(int i = 0; i < queryChar.length -1; i++)
            {
                for(int j = 0; j < termChar.length -1; j++)
                {
                    if(queryChar[i] == termChar[j] )
                    {
                        if((queryChar[i + 1]) == (termChar[j + 1]))
                        {
                            System.out.println((queryChar[i + 1]) + " " + (termChar[j + 1]));
                            int value = map.get(term);
                            map.put(term,++value);
                            break;
                        }
                    }   
                }
            }
            }   
        return map;
    }

    public static void printResults(HashMap<String,Integer> map)
    {
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey()+" : "+entry.getValue());
        }
    }


}
于 2013-07-02T19:22:11.633 回答