фильтровать список строк в C#

#c# #string #filter

#c# #строка #Фильтр

Вопрос:

Я изучаю C #, читая книги и другие онлайн-уроки (homeandlearn.co.uk )

Мне удалось выполнить упражнение FizzBuzz, но я не справляюсь с приведенным ниже упражнением. Любая помощь была бы очень признательна.

Пожалуйста, объясните подробно, чтобы я тоже мог учиться.

Упражнение

фильтровать список строк, которые должны передавать только шестибуквенные строки, состоящие из двух объединенных строк меньшего размера, которые также есть в списке.

Например, учитывая список

acks, top, cat, gr, by, bar, lap, st, ely, ades

Список должен возвращать

стеки, ноутбук, оценки, едва

Потому что это объединение двух других строк:

st acks = стеки

lap top = ноутбук

gr ades = оценки

bar ely = едва

Комментарии:

1. Filter — плохой выбор слов, construct было бы лучше.

2. если только пример не неверен и стеки также не должны быть в списке

3. а как насчет cat top = catop, граки, бяки и т.д.? Упражнение плохо написано.

4. Вам не хватает другого списка: набора словарных слов, ограничивающих потенциальные результаты

5. Я надеюсь, что молодые английские мальчики (и девочки) не обучены английскому языку Ex ercise :- )

Ответ №1:

В LINQ:

 // The strings (it's equivalent to new string[])
var strs = new[] { "acks", "top", "cat", "gr", "by", "bar", "lap", "st", "ely", "ades" };

// We group the strings by length.
var strsByLength = strs.ToLookup(p => p.Length);

// For each string we match the string with all the strings with the "right" length (6 - current string length) and we sum them (p, q) => p   q.
var result = strs.SelectMany(p => strsByLength[6 - p.Length], (p, q) => p   q);
  

Я использую ToLookup , чтобы сделать эту проблему «средней» сложности немного меньше, чем O(n ^ 2). Очевидно, что если все строки имеют длину 3, проблема по-прежнему остается O (n ^ 2).

Я использую SelectMany только это, это немного продвинутый LINQ.

Я добавлю, что если у вас есть словарь «хороших» слов, решением может быть следующее. Он использует словарь как черный ящик: вы можете проверить, есть ли слово В словаре (технически HashSet ), но вы не можете напрямую использовать словарь, чтобы помочь вам найти слова.

 // The list of good words
var words = new[] { "stacks", "laptop", "grades", "barely" };

// Made in an `HashSet` to make it O(1) to check for them.
var wordsSet = new HashSet<string>(words);

// Here we create a temporary object (p, q) => new { p, q, sum = p   q } containing the two "parts" of the word and the complete word and then we filter the result for only the words contained in the wordsSet.
var result2 = strs.SelectMany(p => strsByLength[6 - p.Length], (p, q) => new { p, q, sum = p   q }).Where(p => wordsSet.Contains(p.sum));
  

Ответ №2:

На самом деле есть много способов сделать это. Вот один, который использует сопряжение:

         //grab all possible pairings in one data structure
        List<KeyValuePair<string, string>> pairs = new List<KeyValuePair<string, string>>();
        string[] list = { "acks", "top", "cat", "gr", "by", "bar", "lap", "st", "ely", "ades" };
        foreach (string first in list)
        {
            foreach (string second in list)
            {
                pairs.Add(new KeyValuePair<string, string>(first, second));
            }
        }

        //test each pairing for length and whatever else you want really
        List<string> sixLetterWords = new List<string>();
        foreach (KeyValuePair<string, string> pair in pairs)
        {
            string testWord = pair.Key   pair.Value;
            if (testWord.Length == 6)
            {
                sixLetterWords.Add(testWord);
            }
        }
  

Ответ №3:

Разделяй и властвуй. Во-первых, вам нужно найти способ получить все возможные пары строк (например, first и second, first и third, …, second и third и т.д.). Затем для каждой пары вы проверяете, содержит ли рассматриваемый список либо s1 s2 или s2 s1 .

Комментарии:

1. Спасибо за помощь, как вы знаете, я учусь и довольно хорошо разбираюсь в C #, не могли бы вы, пожалуйста, немного уточнить или даже, если вы можете написать быстрый код, чтобы я мог учиться и следовать. Спасибо

2. Стоит создавать пары, длина соединения которых равна 6.

3. @Mo. — Для нас не имело бы смысла приводить вам пример. То, что предложил Антон, — это тривиальный навык программирования, вам нужно сделать это самостоятельно, иначе вы ничему не научитесь.

Ответ №4:

Самый простой способ — выполнить вложенный цикл for и попробовать каждую комбинацию и проверить, имеет ли она длину 6. Что-то вроде:

 For <each string> AS a
    For <every string> AS b
        If (a b).length = 6 then
            // we have a match!
  

Я оставлю это вам, чтобы перевести это в реальный код

Ответ №5:

Вы уже знаете, как объединить две строки. Вы также знаете, как проверить длину строки.

Итак, создайте новый список из элементов в первом списке и исключите элементы с длиной ! = 6.