#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.