C# 查找具有一定汉明距离LINQ的字符串
如果我们运行以下LINQ查询(感谢@octavioccl的帮助):C# 查找具有一定汉明距离LINQ的字符串,c#,linq,string-matching,hamming-distance,C#,Linq,String Matching,Hamming Distance,如果我们运行以下LINQ查询(感谢@octavioccl的帮助): var result = stringsList .GroupBy(s => s) .Where(g => g.Count() > 1) .OrderByDescending(g => g.Count()) .Select(g => g.Key); 它提供列表中至少出现两次的所有字符串(但完全匹配,即汉明距离=0) 我只是想知道是否有一个优雅的解决方案(到目前为止我尝试
var result = stringsList
.GroupBy(s => s)
.Where(g => g.Count() > 1)
.OrderByDescending(g => g.Count())
.Select(g => g.Key);
它提供列表中至少出现两次的所有字符串(但完全匹配,即汉明距离=0)
我只是想知道是否有一个优雅的解决方案(到目前为止我尝试过的所有解决方案都使用丑陋的循环和计数器或regex),我们可以在where
子句中指定汉明距离,以获得位于指定汉明距离范围内的字符串
p.S:所有字符串的长度都相等
更新
非常感谢克朗托吉安尼斯的详细回答。正如我前面提到的,我想得到汉明距离低于给定阈值的字符串列表。他的代码工作得非常好(再次感谢)
剩下的唯一一件事是将字符串从“resultset”中取出,并插入/添加到“List”中
基本上这就是我想要的:
List<string> outputList = new List<string>();
foreach (string str in patternsList)
{
var rs = wordsList
.GroupBy(w => hamming(w, str))
.Where(h => h.Key <= hammingThreshold)
.OrderByDescending(h => h.Key)
.Select(h => h.Count());
outputList.Add(rs); //I know it won't work but just to show what is needed
}
List outputList=new List();
foreach(模式列表中的字符串str)
{
var rs=wordsList
.GroupBy(w=>hamming(w,str))
.其中(h=>h.键h.键)
.Select(h=>h.Count());
outputList.Add(rs);//我知道它不起作用,只是为了显示需要什么
}
谢谢您可以这样做:
int hammingDistance = 2;
var result = stringsList
.GroupBy(s => s.Substring(0, s.Length - hammingDistance))
.Where(g => g.Count() > 1)
.OrderbyDescending(g => g.Count())
.Select(g => g.Key);
使用LINQ计算两个字符串之间的汉明距离可以优雅地完成:
Func<string, string, int> hamming = (s1, s2) => s1.Zip(s2, (l, r) => l - r == 0 ? 0 : 1).Sum();
案例1
var input = "hello";
var hammingThreshold = 3;
var rs = words
.GroupBy(w => hamming(w, input))
.Where(h => h.Key <= hammingThreshold)
.OrderByDescending(h => h.Key);
案例2
var hs = words
.SelectMany((w1, i) =>
words
.Where((w2, j) => i > j)
.Select(w2 => new { Word1 = w1, Word2 = w2 })) // all word pairs except with self
.GroupBy(pair => hamming(pair.Word1, pair.Word2))
.Where(g => g.Key <= hammingThreshold)
.OrderByDescending(g => g.Key);
编辑仅获取第一组中的单词,您可以使用
选择many
var output = rs.SelectMany(g => g).ToList();
汉明距离适用于等长的弦。所有的字符串都是等长的吗?如果有字符串A、B和C,A与B的距离为1,B与C的距离为1,但A与C的距离大于1,您希望如何对这些字符串进行分组?也就是说,如果它们是数字,并且您希望将最大距离为1的所有数字分组,并且您有数字1、2和3,您希望从中创建什么组?@LasseV.Karlsen Good point Lasse。克朗托的回答很好,谢谢你的回答。巨大的努力!!非常感谢我在选择案例1的
时遇到了一些困难。我只想选择字符串。你可以像我一样对每个组进行迭代。或者你应该更新你的答案,提供更多关于你想做什么的信息。@TalhaIrfan我已经编辑了我的答案,使用第一个案例,只提取单词;也许你根本不需要分组。非常感谢!!你帮了大忙
var hs = words
.SelectMany((w1, i) =>
words
.Where((w2, j) => i > j)
.Select(w2 => new { Word1 = w1, Word2 = w2 })) // all word pairs except with self
.GroupBy(pair => hamming(pair.Word1, pair.Word2))
.Where(g => g.Key <= hammingThreshold)
.OrderByDescending(g => g.Key);
(holla, rellp) (fooba, holla) (hempd, hello) with distance 3
(rellp, hello) (holla, hello) with distance 2
var output = rs.SelectMany(g => g).ToList();