一位朋友问我如何用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;
}
答案 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();
}