使用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; } 

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

一种更加万无一失的方式(如果targetindividual短,上面的代码片会失败):

 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]); } } 

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

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

 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 

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

例如:

 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个字符的差异。

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

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