【发布时间】:2021-05-06 01:27:07
【问题描述】:
我有大约 200,000 个单词需要找到与可以包含任意数量的字母通配符的单词匹配的单词。我还需要查找不带任何通配符的单词的选项。
我已按长度将单词分成集合:
static readonly HashSet<string>[] _validWords = {
new HashSet<string>(StringComparer.OrdinalIgnoreCase), // 3 letter words
new HashSet<string>(StringComparer.OrdinalIgnoreCase), // 4 letter words
new HashSet<string>(StringComparer.OrdinalIgnoreCase), // 5 letter words
new HashSet<string>(StringComparer.OrdinalIgnoreCase), // 6 letter words
new HashSet<string>(StringComparer.OrdinalIgnoreCase), // 7 letter words
new HashSet<string>(StringComparer.OrdinalIgnoreCase), // 8 letter words
new HashSet<string>(StringComparer.OrdinalIgnoreCase) // 9 letter words
};
搜索特定单词很简单:
public static bool IsValid(string word) {
return word.Length >= GameplaySettings.Instance.MinWordLength && _validWords[word.Length - 3].Contains(word);
}
这是我目前使用正则表达式查找通配符的实现(最终我想得到 all 匹配的单词,但现在只找到一个(或没有)就可以了。):
public static bool IsValidRegex(string pattern, int length) {
pattern = $"^{pattern}$";
foreach (string word in _validWords[length - 3]) {
if (Regex.Matches(word, pattern, RegexOptions.Singleline).Count > 0) { return true; }
}
return false;
}
可以有任意数量的通配符(例如,all 字母甚至可以是通配符),而且它目前的性能不如我希望的那样。
所以我想知道是否有更有效的方法!
感谢您的任何帮助/建议!
【问题讨论】:
-
在这里使用 hashet 没有任何好处。也许您需要想出某种可以搜索的树结构。
-
“不幸的是,我尝试的实现没有奏效” - 因为
HashSet<T>在这种情况下根本没有帮助,如果你提供一个适当的问题,你的问题会更好minimal reproducible example 展示了您尝试过的内容,并详细说明了实际做了什么、您希望它做什么以及具体您需要什么帮助。 -
@PeterDuniho - 我是否错误地认为用于查找特定条目的 HashSet 比迭代数组或列表更快?它是一个 HashSet,因为这是必需的功能,而不是复制数据,我正在寻找使用相同容器的解决方案。
-
HashSet 的查找速度更快,因为它不会遍历其所有项目:它使用您正在查找的对象的哈希码在哈希集中内部找到正确的分区,然后进行比较每个项目都有一个匹配的哈希码,直到找到有问题的项目。因此,您可能只比较 1(取决于哈希码冲突),而不是比较
.Count项目。迭代哈希集并不比迭代数组或列表快,而这正是您正在做的。 -
@Llama 是的,这是我的理解,所以我使用 HashSet 是因为我确实需要查找特定的单词,而且我还需要单独查找通配符匹配项。我已经用我当前的实现更新了这个问题,希望能更好地解释它。