【问题标题】:ASP.NET MVC best way for searching anagrams in a databaseASP.NET MVC 在数据库中搜索字谜的最佳方法
【发布时间】:2020-06-29 00:28:54
【问题描述】:

我正在做一个迷你项目并尝试制作一个程序,当你输入一个单词时,它会从大约 70000 个单词的大数据库中找到字谜,它还需要具有相同数量的字符,例如(狗= 神,而不是神或狗)。

到目前为止,我设法进行了搜索,当我搜索时,我会找到所有包含我所写单词一部分的单词

public ActionResult CheckAnagram(string word)
{
        IQueryable<Anagram> wordDictionary = db.Anagrams;
        if (!String.IsNullOrEmpty(word))
        {
            wordDictionary = wordDictionary.Where(a => a.Name.Contains(word));
        }

        return View(wordDictionary.ToList());
}

我不确定这样做的最佳主意是什么,这是一个相当大的数据库,我可以想象的是我必须多次去并不断重新排序单词以检查每种可能性。

这是最好的解决方案吗?还是有其他方法?

我知道如何编写此代码,但在我看来这似乎不是最好的方法。万一不是很明显,我是个初学者...

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core ef-code-first


    【解决方案1】:

    一种简单的方法是将每个单词存储在这样的表中:

    Key    | Value
    ---------------
    dgo    | dog
    dgo    | god
    act    | act
    act    | cat
    act    | tac
    

    键是按字母顺序排列的单词的字母,而值是实际单词。

    然后,要查找tac 的字谜,您只需按字母顺序排列字母,然后执行简单的查找。

    这将使您获得非常快的性能。

    一个简单的优化是对键进行哈希处理,以提高查找速度并减少数据存储,但代价是必须确认每个单词都是真正的字谜(因为哈希可能导致冲突,尽管这种情况非常罕见)。

    显然,如果您将存储在数据库中,那么将键和值存储在单独的表中并将它们连接在一起可能会提供出色的性能,但是对于 70k 单词,它对于一个玩具项目来说已经足够快了,无论您如何实现它.

    编辑

    此代码的简单“内存”示例如下:

    void Main()
    {
        // Setup a database of anagrams. We are using a simple 
        // dictionary here.
        var words = new Dictionary<string, IEnumerable<string>> 
        {
            ["dgo"] = new List<string> { "dog", "god"},
            ["act"] = new List<string> { "act", "cat", "tac" }
        };
    
        // Ask the user for a word to search.
        var wordToSearch = Console.ReadLine();
    
        // Get the lookup key.
        var key = GetKey(wordToSearch);
    
        // Lookup the anagrams, excluding the word that was input.
        var anagrams = words[key].Where(word => word != wordToSearch);
    
        // Print out the anagrams.
        foreach(var anagram in anagrams)
        {
            Console.WriteLine(anagram);
        }
    }
    
    // Calculates a key for "word". This function must return a value that 
    // will be the same for any anagram of "word".
    public string GetKey(string word)
    {
        return new String(word.OrderBy(c => c).ToArray());
    }
    

    编辑2

    从文本文件构造字典:

    我假设您的文本文件如下所示:

    cat
    dog
    tac
    act
    god
    

    那么下面的代码就可以读进去了:

    var file = @"C:\temp\words.txt";
    var words = new Dictionary<string, IList<string>>(); 
    
    using (var stream = File.OpenRead(file))
    using (var reader = new StreamReader(stream))
    {
        while(!reader.EndOfStream)
        {
            var word = reader.ReadLine().Trim();
            var key2 = GetKey(word);
    
            if (!words.ContainsKey(key2))
            {
                words[key2] = new List<string>();
            }
    
            words[key2].Add(word);
        }
    }
    

    【讨论】:

    • 我不确定我是否理解,目前我只有 70k 字的文本文件,我如何将它安排在 2 个表中?因为有各种各样的词,我看不到这样做的方法,除非制作文件的人知道以某种方式排列它们,到目前为止它们是按字母顺序排列的。你能告诉我在我的情况下怎么做吗?我看不到修改此表以使其看起来像您的示例的方法:)
    • 我认为这可能是一个有趣的例子,因为它可能恰好有一个包含大量数据的文件,我们需要用它做不同的事情,这就是我想要学习的,如果我有这个文件,我可以用我放在表中搜索字谜的数据做什么
    • @sgcata 我添加了一些代码,显示如何将文本文件读入字典。但是,您的问题开始超出原始问题的范围 - 如果您有任何新问题,我可以建议您提出新问题吗...?
    • 嗨,我感谢从文件中读取的帮助,但我之前已经找到了一种读取方法,正如我所写的,我已经在我创建的这个数据库中进行了搜索。但现在我需要一种方法来找到字谜。所以我已经有了数据库,现在当我写“Listen”时,它需要搜索数据库并找到“Silent”以及那里可能存在的任何其他字谜。这就是我的问题,我可以使用哪种方式来实现这一目标?如果您可以帮助我,我可以给出最佳答案,到目前为止,我还没有在网上找到如何至少以某种方式有效地做到这一点。谢谢:D
    • 我的意思是我可以搜索每个单词并重新对齐两个单词,然后查看它们是否相等,但我不确定这是一个好方法。我可能会开始这样做,如果我同时找到另一种方法,我会改变它
    猜你喜欢
    • 2010-11-13
    • 1970-01-01
    • 2017-07-27
    • 2011-09-18
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    相关资源
    最近更新 更多