Логика расширения запроса в C # - PullRequest
3 голосов
/ 16 марта 2012

Я должен написать логику для расширения запросов для поисковой системы Solr. Я использую Dictionary<string, string> dicSynon = new Dictionary<string, string>();.

Каждый раз я буду получать строки типа «2 ln ca». В моем словаре у меня синонимы для ln и ca как lane и california. Теперь мне нужно передать solr все комбинации строк. Как это

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

Пожалуйста, помогите мне построить логику ....

1 Ответ

5 голосов
/ 16 марта 2012

Это упражнение по использованию комбинаторики и Linqs SelectMany:

Сначала вы должны написать себе какую-нибудь функцию, чтобы дать вам последовательность синонимов для данного слова (включая слово, поэтому «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));
    }

}

Не стесняйтесь комментировать, если что-то здесь не совсем ясно;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...