使用LINQ计算两个字符串之间的匹配字符

时间:2009-08-16 21:08:39

标签: c# linq

一位朋友问我如何用LINQ改进一些代码。你如何通过两个字符串之间的字符比较来计算索引的匹配数?这是原始代码,可以用LINQ进行改进吗?

private int Fitness(string individual, string target)
   {
       int sum = 0;
       for (int i = 0; i < individual.Length; i++)
           if (individual[i] == target[i]) sum++;
       return sum;
   }

4 个答案:

答案 0 :(得分:5)

return Enumerable.Range(0, individual.Length)
                 .Count(i => individual[i] == target[i]);

一种更加万无一失的方法(如果target短于individual,则上述代码段会失败):

return Enumerable.Range(0, Math.Min(individual.Length, target.Length))
                 .Count(i => individual[i] == target[i]);

我相信代码是正确的。 Enumerable.Range方法有两个参数。第一个是起始索引(应为0),第二个是项目数。要测试并确保完整的代码段:

class Program {
  static void Main(string[] args) {
      Console.WriteLine(Fitness("hello", "world"));
  }
  static int Fitness(string individual, string target) {
      return Enumerable.Range(0, Math.Min(individual.Length, target.Length))
                       .Count(i => individual[i] == target[i]);
  }
}

答案 1 :(得分:2)

可以用LINQ编写类似的内容,但由于“Zip”在.NET 4.0之前没有内置,因此代码将超出我们的预期,和/或效率不高。我很想“按原样”保留它,但我可能会检查target.Length以避免超出范围的异常。

也许我会做一个扩展方法,但是:

public static int CompareFitness(this string individual, string target)
{
   int sum = 0, len = individual.Length < target.Length
        ? individual.Length : target.Length;
   for (int i = 0; i < len; i++)
       if (individual[i] == target[i]) sum++;
   return sum;
}

然后你可以使用:

string s = "abcd";
int i = s.CompareFitness("adc"); // 2

答案 2 :(得分:0)

当前选择的答案并不能很好地处理不同长度的字符串。如果长度不同,它只比较输入字符串的最大子字符串。

例如:

Fitness("ABC", "ABC") -> 3
Fitness("ABC", "ABC this is an 'unfit' string") -> 3

这可以通过从您的分数中减去不同的长度来轻松解决。改进:

return Enumerable.Range(0, Math.Min(individual.Length, target.Length))
                 .Count(i => individual[i] == target[i])
                 - Math.Abs(individual.Length - target.Length);

现在:

Fitness("ABC", "ABC") -> 3
Fitness("ABC", "ABC this is an 'unfit' string") -> -23

从技术上讲,这两个输入之间有23个字符差异。

答案 3 :(得分:-1)

加入怎么样,还是我误解了?

    static void Main(string[] args)
    {
        var s1 = "abcde";
        var s2 = "hycdh";
        var count = s1.Join(s2, c => c, c => c, (a,b) => a).Count();
        Console.WriteLine(count);
        Console.ReadKey();
    }