отфильтровать список строк в C # - PullRequest
0 голосов
/ 05 октября 2011

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

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

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

Excercise

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

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

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

Список должен вернуть

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

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

st + acks = стеки

круг + верх = ноутбук

гр + ады = оценки

bar + ely = едва

Ответы [ 5 ]

1 голос
/ 05 октября 2011

В 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));
0 голосов
/ 05 октября 2011

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

        //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);
            }
        }
0 голосов
/ 05 октября 2011

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

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

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

0 голосов
/ 05 октября 2011

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

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

0 голосов
/ 05 октября 2011

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

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