使用C#在数组中进行松散字符串搜索
本文关键字:字符串 搜索 数组 使用 | 更新日期: 2023-09-27 18:30:07
假设我们有一个
string[] array = {"telekinesis", "laureate", "Allequalsfive", "Indulgence"};
我们需要在这个数组中找到一个单词
通常我们会做以下操作:(或使用任何类似的方法来查找字符串)
bool result = array.Contains("laureate"); // returns true
在我的情况下,我正在搜索的单词可能有错误(正如标题所示)。
例如,我无法区分字母"I"(大"I")和"l"(小"l")以及"1"(数字1)之间的区别。
有没有办法找到一个词,比如"Allequalsive"、"A11equalsive"或"AIEqualsfive"?(松散搜索)通常结果为"false"。
如果我能指定忽略一些字母就好了。。(序列是常量,其他字母是常量)。
借助扩展方法&Levenstein距离算法
var array = new string[]{ "telekinesis", "laureate",
"Allequalsfive", "Indulgence" };
bool b = array.LooseContains("A11equalsfive", 2); //returns true
-
public static class UsefulExtensions
{
public static bool LooseContains(this IEnumerable<string> list, string word,int distance)
{
foreach (var s in list)
if (s.LevenshteinDistance(word) <= distance) return true;
return false;
}
//
//http://www.merriampark.com/ldcsharp.htm
//
public static int LevenshteinDistance(this string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
return m;
if (m == 0)
return n;
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++){}
for (int j = 0; j <= m; d[0, j] = j++){}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (char.ToUpperInvariant(t[j - 1]) == char.ToUpperInvariant(s[i - 1])) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
}
您可以使用接受IEqualityComparer<TSource>
的Contains
重载。
实现你自己的平等比较器,忽略你想要的字母,然后离开。
如果你只需要知道这个词是否松散地包含在你的数组中,那么你可以在搜索词和数组中"清除"你想要忽略的字母(例如用"l"代替"1"):
Func<string, string> clean = x => x.ToLower().Replace('1', 'l');
var array = (new string[] { "telekinesis", "laureate", "A11equalsfive", "Indulgence" }).Select(x => clean(x));
bool result = array.Contains(clean("allequalsfive"));
否则,您可以查找Where()LINQ关键字,该关键字允许您根据指定的函数筛选数组。