代码之家  ›  专栏  ›  技术社区  ›  Jon Galloway

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

  •  3
  • Jon Galloway  · 技术社区  · 15 年前

    一个朋友问我如何用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 回复  |  直到 9 年前
        1
  •  5
  •   Mehrdad Afshari    15 年前
    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]);
      }
    }
    
        2
  •  2
  •   Marc Gravell    15 年前

    能够 写一些类似于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
    
        3
  •  0
  •   jamesrom    9 年前

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

    例如:

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

        4
  •  -1
  •   spender    15 年前

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

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