Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 查找具有一定汉明距离LINQ的字符串_C#_Linq_String Matching_Hamming Distance - Fatal编程技术网

C# 查找具有一定汉明距离LINQ的字符串

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) 我只是想知道是否有一个优雅的解决方案(到目前为止我尝试

如果我们运行以下LINQ查询(感谢@octavioccl的帮助):

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();