将字符串列表与可用的字典/词库进行比较

4

我有一个程序(C#),它生成了一个字符串列表(原始字符串的排列组合)。大多数字符串都是符合预期的原始字母的随机分组(例如etam,aemt,team)。我想以编程方式找到列表中的一个实际英语单词。我需要一个同义词词典/字典来查找和比较每个字符串。有人知道可用的资源吗?我在C#中使用VS2008。

2个回答

3
你可以从网络上下载一个单词列表(例如这里提到的文件之一:http://www.outpost9.com/files/WordLists.html),然后快速执行以下操作:
// Read words from file.
string [] words = ReadFromFile();

Dictionary<String, List<String>> permuteDict = new Dictionary<String, List<String>>(StringComparer.OrdinalIgnoreCase);

foreach (String word in words) {
    String sortedWord = new String(word.ToArray().Sort());
    if (!permuteDict.ContainsKey(sortedWord)) {
        permuteDict[sortedWord] = new List<String>();
    }
    permuteDict[sortedWord].Add(word);
}

// To do a lookup you can just use

String sortedWordToLook = new String(wordToLook.ToArray().Sort());

List<String> outWords;
if (permuteDict.TryGetValue(sortedWordToLook, out outWords)) {
    foreach (String outWord in outWords) {
        Console.WriteLine(outWord);
    }
}

谢谢。我的主要关注点是从哪里获取单词列表(是否有现成的资源可用),最好是英语语言的广泛代表。 但是您的代码已经回答了我可能会有的任何进一步问题...“那么我该如何使用它?” 谢谢 - sMaN
+1 我会选择这个解决方案,因为它很可能提供最佳性能。不过我可能只是把每个单词放在一个 HashSet<string> 中 - 因为这里没有“值”,只有一组单词。 - Andras Zoltan
@Andras:实际上,每个可能的输入都可以映射到一个单词列表,比如积分、三角形等。我们实际上应该存储一个单词列表。我会更改代码以反映这一点。 - Aryabhatta

1

你也可以使用维基词典。MediaWiki API(维基词典使用MediaWiki)允许你查询文章标题列表。在维基词典中,文章标题是字典中的词条之一。唯一的问题是,外语单词也包含在字典中,所以有时可能会得到“不正确”的匹配结果。当然,你的用户还需要互联网访问权限。你可以在以下链接获取API的帮助和信息:http://en.wiktionary.org/w/api.php

这是一个查询URL的示例:

http://en.wiktionary.org/w/api.php?action=query&format=xml&titles=dog|god|ogd|odg|gdo

这将返回以下xml:

<?xml version="1.0"?>
<api>
  <query>
    <pages>
      <page ns="0" title="ogd" missing=""/>
      <page ns="0" title="odg" missing=""/>
      <page ns="0" title="gdo" missing=""/>
      <page pageid="24" ns="0" title="dog"/>
      <page pageid="5015" ns="0" title="god"/>
    </pages>
  </query>
</api>

在C#中,您可以使用System.Xml.XPath获取所需的部分(具有pageid的页面项)。这些是“真正的单词”。
我编写了一个实现并进行了测试(使用上面简单的“狗”示例)。它只返回了“dog”和“god”。您应该进行更广泛的测试。
public static IEnumerable<string> FilterRealWords(IEnumerable<string> testWords)
{
    string baseUrl = "http://en.wiktionary.org/w/api.php?action=query&format=xml&titles=";
    string queryUrl = baseUrl + string.Join("|", testWords.ToArray());

    WebClient client = new WebClient();
    client.Encoding = UnicodeEncoding.UTF8; // this is very important or the text will be junk

    string rawXml = client.DownloadString(queryUrl);

    TextReader reader = new StringReader(rawXml);
    XPathDocument doc = new XPathDocument(reader);
    XPathNavigator nav = doc.CreateNavigator();
    XPathNodeIterator iter = nav.Select(@"//page");

    List<string> realWords = new List<string>();
    while (iter.MoveNext())
    {
        // if the pageid attribute has a value
        // add the article title to the list.
        if (!string.IsNullOrEmpty(iter.Current.GetAttribute("pageid", "")))
        {
            realWords.Add(iter.Current.GetAttribute("title", ""));
        }
    }

    return realWords;
}

这样调用:

IEnumerable<string> input = new string[] { "dog", "god", "ogd", "odg", "gdo" };
IEnumerable<string> output = FilterRealWords(input);

我尝试使用LINQ to XML,但我对它不是很熟悉,所以这让我很头疼,最终放弃了。


我认为在这里应该使用带有WebHttpBinding的WCF进行Web服务调用。这很容易做到,您将能够获得对象列表作为结果,然后可以使用LINQ-to-Objects对其进行操作。 - casperOne
@casperOne。啊,我以前从未使用过WCF,所以对它完全不熟悉。WebClient和XPath都很容易实现,然而。我首先编写了LINQ to XML,基本上使用了与上面相同的逻辑,但该死的东西一直返回ILinqQueryable或其他我不想要的对象。设置和使用WCF容易吗? - Benny Jobigan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接