Предполагая, что слова в словаре не содержат друг друга (например, «TOO» и «TOOK»), я не понимаю, почему эта проблема требует более сложного решения, чем эта однострочная функция:
static public List<string> Normalize(string input, List<string> dictionary)
{
return dictionary.Where(a => input.Contains(a)).ToList();
}
(Если слова ДЕЙСТВИТЕЛЬНО содержат друг друга, см. ниже.)
Полный пример:
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
static public List<string> Normalize(string input, List<string> dictionary)
{
return dictionary.Where(a => input.Contains(a)).ToList();
}
public static void Main()
{
List<string> dictionary = new List<string>
{
"COMPUTER","FIVE","CODE","COLOR","FOO"
};
string input = "COMPUTERFIVECODECOLORBAR";
var normalized = Normalize(input, dictionary);
foreach (var s in normalized)
{
Console.WriteLine(s);
}
}
}
Вывод:
COMPUTER
FIVE
CODE
COLOR
Код на DotNetFiddle
С другой стороны, если вы определили, что ваши ключевые слова ДЕЙСТВИТЕЛЬНО перекрываются, вам не повезло. Если вы уверены, что входная строка содержит только слова из словаря и что они непрерывны, вы можете использовать более сложную функцию.
static public List<string> Normalize2(string input, List<string> dictionary)
{
var sorted = dictionary.OrderByDescending( a => a.Length).ToList();
var results = new List<string>();
bool found = false;
do
{
found = false;
foreach (var s in sorted)
{
if (input.StartsWith(s))
{
found = true;
results.Add(s);
input = input.Substring(s.Length);
break;
}
}
}
while (input != "" && found);
return results;
}
public static void Main()
{
List<string> dictionary = new List<string>
{
"SHORT","LONG","LONGER","FOO","FOOD"
};
string input = "FOODSHORTLONGERFOO";
var normalized = Normalize2(input, dictionary);
foreach (var s in normalized)
{
Console.WriteLine(s);
}
}
Это работает так, что он просматривает только начало строки и сначала ищет самые длинные ключевые слова. Когда он найден, он удаляет его из входной строки и продолжает поиск.
Вывод:
FOOD
SHORT
LONGER
FOO
Обратите внимание, что «LONG» не включено, потому что мы включили «LONGER», но «FOO» включено, потому что оно находится в строке отдельно от «FOOD».
Кроме того, при использовании этого второго решения ключевые слова появятся в словаре результатов в том же порядке, в котором они появились в исходной строке. Таким образом, если требуется фактически разделить фразу, а не просто определить ключевые слова в любом порядке, вам следует использовать вторую функцию.
Код
person
John Wu
schedule
14.11.2017