【问题标题】:Returning potential strings from a list of strings and their next chars performance从字符串列表中返回潜在的字符串及其下一个字符的性能
【发布时间】:2012-01-25 18:27:50
【问题描述】:

这是一个关于从字符串数组中高效返回字符串和字符的问题,其中:

  1. 字符串数组中的字符串以提供的用户输入开始
  2. 这些字符串的下一个字母作为字符的集合。

这个想法是,当用户键入一个字母时,潜在的响应会与他们的下一个字母一起显示。因此响应时间很重要,因此需要高性能算法。

例如如果字符串数组包含:

string[] stringArray = new string[] { "Moose", "Mouse", "Moorhen", "Leopard", "Aardvark" };

如果用户键入“Mo”,则应返回“Moose”、“Mouse”和“Moorhen”以及可能的下一个字母的字符“o”和“u”。

这感觉像是 LINQ 的工作,所以我当前作为静态方法的实现是(我将输出存储到 Suggestions 对象,该对象仅具有 2 个返回列表的属性):

public static Suggestions 
GetSuggestions
    (String userInput, 
    String[] stringArray)
{
    // Get all possible strings based on the user input. This will always contain
    // values which are the same length or longer than the user input.
    IEnumerable<string> possibleStrings = stringArray.Where(x => x.StartsWith(userInput));
    IEnumerable<char> nextLetterChars = null;

    // If we have possible strings and we have some input, get the next letter(s)
    if (possibleStrings.Any() &&
        !string.IsNullOrEmpty(userInput))
    {
        // the user input contains chars, so lets find the possible next letters.
        nextLetterChars =
            possibleStrings.Select<string, char>
            (x =>
            {
                // The input is the same as the possible string so return an empty char.
                if (x == userInput)
                {
                    return '\0';
                }
                else
                {
                    // Remove the user input from the start of the possible string, then get
                    // the next character.
                    return x.Substring(userInput.Length, x.Length - userInput.Length)[0];
                }
            });
    } // End if

我实现了第二个版本,它实际上将所有输入组合存储到一个字典列表中;每个单词一个,组合键和值作为实际所需的动物,例如:

  • 字典 1:
  • 键值
  • “M”“驼鹿”
  • “MO“驼鹿”

等等

  • 字典 2:
  • 键值
  • “M”“鼠标”
  • “MO”“鼠标”

等等

由于字典访问的检索时间为 O(1) - 我认为这可能是一个更好的方法。

所以在启动时加载字典:

    List<Dictionary<string, string>> animalCombinations = new List<Dictionary<string, string>>();
    foreach (string animal in stringArray)
    {
        Dictionary<string, string> animalCombination = new Dictionary<string, string>();
        string accumulatedAnimalString = string.Empty;
        foreach (char character in animal)
        {
            accumulatedAnimalString += character;
            animalCombination[accumulatedAnimalString] = animal;
        }

        animalCombinations.Add(animalCombination);
    }

然后在运行时获取可能的字符串:

    // Select value entries from the list of dictionaries which contain
    // keys which match the user input and flatten into one list.
    IEnumerable<string> possibleStrings = 
        animalCombinations.SelectMany
            (animalCombination => 
                {
                    return animalCombination.Values.Where(x =>
                        animalCombination.ContainsKey(userInput));
                });

所以问题是:

  1. 哪种方法更好?
  2. 有没有更好的方法来获得更好的性能?
  3. LINQ 表达式的处理成本高吗?

谢谢

【问题讨论】:

标签: c# .net string performance algorithm


【解决方案1】:

哪种方法更好?

可能是字典方法,但您必须进行分析才能找到。

有没有更好的性能更好的方法?

使用prefix tree

LINQ 表达式的处理成本高吗?

如果写得正确,它们会非常为相同代码的命令式版本增加很少的开销。由于它们更易于阅读、维护和编写,因此它们通常是要走的路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-23
    • 1970-01-01
    • 2012-10-15
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    • 2020-01-27
    相关资源
    最近更新 更多