【问题标题】:How to do a search from a list with non-prefix keywords如何使用非前缀关键字从列表中进行搜索
【发布时间】:2011-02-06 14:20:20
【问题描述】:

我正在编写一个程序来从列表中搜索名称,即使关键字不在名称前面,我也需要找到它们(我的意思是非前缀)

例如如果我的列表是乐器并且我在搜索文本框中键入 "guit"
它应该找到名称​​“Guitar, Guitarrón, Acoustic Guitar, Bass Guitar, ...”
或类似 Longdo Dictionary's 的搜索建议。

这是我的简单而愚蠢的算法(这就是我能做的)

    const int SEARCHROWLIMIT = 30;
    private string[] DoSearch(string Input, string[] ListToSearch)
    {
        List<string> FoundNames = new List<string>();

        int max = 0;
        bool over = false;
        for (int k = 0; !over; k++)
        {
            foreach (string item in ListToSearch)
            {
                max = (max > item.Length) ? max : item.Length;
                if (k > item.Length) continue;
                if (k >= max) { over = true; break; }
                if (!Input.Equals("Search")
                    && item.Substring(k, item.Length - k).StartsWith(Input, StringComparison.OrdinalIgnoreCase))
                {
                    bool exist = false;
                    int i = 0;
                    while (!exist && i < FoundNames.Count)
                    {
                        if (item.Equals(FoundNames[i]))
                        {
                            exist = true;
                            break;
                        }
                        i++;
                    }
                    if (!exist && FoundNames.Count < SEARCHROWLIMIT)
                        FoundNames.Add(item);
                    else if (FoundNames.Count >= SEARCHROWLIMIT) over = true;
                }
            }
        }
        return FoundNames.ToArray();
    }

我认为这个算法对于大量名称来说太慢了,经过几次反复试验,我决定添加 SEARCHROWLIMIT 来中断操作 而且我也认为有一些现成的方法可以做到这一点。

另一个问题是我需要按类别搜索乐器,如弦乐、打击乐器…… 和原产国。所以我需要按类型和国家/地区过滤器搜索它们。

我怎样才能做到这一点?

【问题讨论】:

  • 您的示例仅给出搜索查询位于单词开头的情况。如果它位于单词的中间,例如从 abcxyzdef 之类的词中搜索 xyz 怎么办?

标签: c# search autosuggest


【解决方案1】:

使用 LINQ,您可以编写如下代码:

var resultSet = products

    // filter products by category
    .Where(product => product.Category == "strings")

    // filter products by origin
    .Where(product => product.Origin == "italy")

    // filter products whose name contains a word starting with "guit"
    .Where(product => (" " + product.Name).Contains(" guit"))

    // limit the result set to the first 30 matching products
    .Take(30);

如果您的产品集相当小,您可以使用 LINQ-to-Objects。否则,您应该使用数据库并查看 LINQ-to-SQL。

【讨论】:

  • 小心。显然不欢迎推荐数据库!
【解决方案2】:

一个字。数据库!

说真的,如果您想进行所有这些不同的搜索,请考虑将您的数据放入数据库中,该数据库的架构可以简化您遇到的分类问题。 Sql Server Express 现在支持full text search,这对于您尝试执行的搜索非常有用。

有一篇很好的博文 here 关于使用 FTS 和 Linq-to-Sql。

【讨论】:

    【解决方案3】:
    static List<string> GetItemsWithWordsStartingWithSubstring(List<string> list, string substring)
    {
        var query = from str in list
                    from item in str.Split(' ')
                    where item.StartsWith(substring, StringComparison.InvariantCultureIgnoreCase)
                    select str;
    
        return query.ToList();
    }
    

    我希望我已经正确阅读了您最初的问题。此函数将返回列表中包含以您的子字符串开头的单词的任何项目。可以在拆分参数中添加更多标点符号。给定一个包含以下内容的列表:

    "abcdef","defabc","def abc","xyz"

    搜索“abc”会找到“abcdef”和“def abc”,但不会找到“defabc”。

    【讨论】:

    • 非常感谢所有的答案。现在我在没有发明任何算法的情况下找到了最好的搜索。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多