2010-02-11 8 views
4

J'ai un programme (C#) qui génère une liste de chaînes (permutations d'une chaîne originale). La plupart des chaînes sont un regroupement aléatoire des lettres originales comme prévu (ie etam, aemt, team). Je veux trouver la chaîne dans la liste qui est un mot anglais, par programmation. J'ai besoin d'un thésaurus/dictionnaire pour rechercher et comparer chaque chaîne. Tout le monde connaît une ressource disponible. Im en utilisant VS2008 en C#.Comparaison de listes de chaînes avec un dictionnaire/thesaurus disponible

Répondre

2

Vous pouvez télécharger une liste de mots à partir du Web (par exemple l'un des fichiers mentionnés ici: http://www.outpost9.com/files/WordLists.html), puis ensuite faire un rapide:

// 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); 
    } 
} 
+0

Merci. Ma principale préoccupation était de savoir où trouver une liste de mots, (s'il y a une ressource prête disponible), qui est de préférence une représentation assez étendue de la langue anglaise. Mais votre code a répondu à d'autres questions que je devrais être ... "alors comment l'utiliser ??" Merci – sMaN

+0

Peut-être que cela va aider: http://www.outpost9.com/files/WordLists.html –

+0

+1 Je choisirais cette solution car elle est susceptible de fournir les meilleures performances. Je vais probablement coller chaque mot dans un HashSet , cependant - puisqu'il n'y a pas de 'valeur' ​​ici - juste un ensemble de mots. –

1

Vous pouvez également utiliser Wiktionnaire. L'API MediaWiki (Wikionary utilise MediaWiki) vous permet de rechercher une liste de titres d'articles. En wiktionary, les titres d'articles sont (entre autres choses) des entrées de mots dans le dictionnaire. Le seul problème est que les mots étrangers sont également dans le dictionnaire, de sorte que vous pourriez obtenir des correspondances "incorrectes" parfois. Votre utilisateur aura également besoin d'un accès Internet, bien sûr. Vous pouvez obtenir de l'aide et des informations sur l'api à: http://en.wiktionary.org/w/api.php

Voici un exemple de l'URL de votre requête:

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

Cela renvoie le code XML suivant:

<?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> 

En C#, vous pouvez alors utilisez System.Xml.XPath pour obtenir les pièces dont vous avez besoin (éléments de page avec pageid). Ce sont les "vrais mots".

J'ai écrit une implémentation et l'ai testée (en utilisant l'exemple simple de "chien" ci-dessus). Il est revenu juste "chien" et "dieu". Vous devriez le tester plus largement.

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; 
} 

appel comme ceci:

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

J'essayé d'utiliser LINQ to XML, mais je ne suis pas familier avec elle, il était donc une douleur et j'ai abandonné là-dessus.

+0

Je pense que WCF avec un WebHttpBinding devrait être utilisé ici pour l'appel de service Web. C'est assez facile à faire, et vous pourriez obtenir le résultat sous la forme d'une liste d'objets, que vous pourriez ensuite utiliser dans LINQ-to-Objects. – casperOne

+0

@casperOne. Ah, je n'ai jamais utilisé la WCF auparavant, donc je ne suis pas familier avec ça. WebClient et XPath étaient assez faciles à faire, cependant. J'ai d'abord écrit le LINQ en XML, en utilisant essentiellement le même type de logique que ci-dessus, mais la chose reprochée continuait à renvoyer un ILinqQueryable ou quelque chose d'autre que l'objet-que-je-voulais. WCF est-il facile à installer et à utiliser? –