2012-03-16 61 views
3

我必须编写用于扩展solr搜索引擎查询的逻辑。我正在使用 Dictionary<string, string> dicSynon = new Dictionary<string, string>();查询C#中的扩展逻辑

每次我都会像“2 ln ca”那样创建字符串。在我的字典中,我有ln和ca的同义词,分别为lane和california。现在我需要传递所有字符串的组合。像这样

2 ln ca 
2 lane ca 
2 lane california 
2 ln california 

请帮我建立逻辑....

+0

可能重复[获取所有可能的字词组合](http://stackoverflow.com/questions/4290889/get-all-possible-word-combinations) – 2012-03-16 05:50:56

回答

5

这在使用组合数学和Linqs一个的SelectMany锻炼:

首先,你必须writeyourself一些功能给你同义词的序列给出一个单词(包括话,那么将导致(“2”),“2”) - 我们称之为“Synonmys” - 使用字典也可以是这样的:

private Dictionary<string, IEnumerable<string>> synonyms = new Dictionary<string, IEnumerable<string>>(); 

public IEnumerable<string> GetSynonmys(string word) 
{ 
    return synonyms.ContainsKey(word) ? synonyms[word] : new[]{word}; 
} 

(你必须自己填写字典...)

有了这个你的任务是相当容易 - 只要想一想。您必须将单词的每个同义词与您在其他单词上完成任务时获得的所有组合结合在一起 - 这正是您可以使用SelectMany的地方(我只将其余部分粘贴到空间中 - 也许您应该重构一下) - 算法自己是标准的递归组合的算法 - 你会看到这个有很多,如果你知道这样的问题:

public string[] GetWords(string text) 
{ 
    return text.Split(new[]{' '}); // add more seperators if you need 
} 

public IEnumerable<string> GetCombinations(string[] words, int lookAt = 0) 
{ 
    if (lookAt >= words.Length) return new[]{""}; 

    var currentWord = words[lookAt]; 
    var synonymsForCurrentWord = GetSynonmys(currentWord); 
    var combinationsForRest = GetCombinations(words, lookAt + 1); 

    return synonymsForCurrentWord.SelectMany(synonym => combinationsForRest.Select(rest => synonym + " " + rest)); 
} 

下面是一个完整的例子:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var test = new Synonmys(Tuple.Create("ca", "ca"), 
           Tuple.Create("ca", "california"), 
           Tuple.Create("ln", "ln"), 
           Tuple.Create("ln", "lane")); 

     foreach (var comb in test.GetCombinations("2 ln ca")) 
      Console.WriteLine("Combination: " + comb); 
    } 
} 

class Synonmys 
{ 
    private Dictionary<string, IEnumerable<string>> synonyms; 

    public Synonmys(params Tuple<string, string>[] syns) 
    { 
     synonyms = syns.GroupBy(s => s.Item1).ToDictionary(g => g.Key, g => g.Select(kvp => kvp.Item2)); 
    } 

    private IEnumerable<string> GetSynonmys(string word) 
    { 
     return synonyms.ContainsKey(word) ? synonyms[word] : new[]{word}; 
    } 

    private string[] GetWords(string text) 
    { 
     return text.Split(new[]{' '}); // add more seperators if you need 
    } 

    private IEnumerable<string> GetCombinations(string[] words, int lookAt = 0) 
    { 
     if (lookAt >= words.Length) return new[]{""}; 

     var currentWord = words[lookAt]; 
     var synonymsForCurrentWord = GetSynonmys(currentWord); 
     var combinationsForRest = GetCombinations(words, lookAt + 1); 

     return synonymsForCurrentWord.SelectMany(synonym => combinationsForRest.Select(rest => synonym + " " + rest)); 
    } 

    public IEnumerable<string> GetCombinations(string text) 
    { 
     return GetCombinations(GetWords(text)); 
    } 

} 

随意如果这里的东西不是很清晰的话,请点评);

+0

Carsten It works :)。非常感谢你。 – Varun 2012-03-16 07:16:26