如何使用LINQ获取两个字符串中的差异字符(含重复次数差异)
如何用LINQ获取两个字符串中的差异字符(考虑重复项)
你遇到的问题其实是因为LINQ的Except、Intersect这类方法是集合级别的操作——它们只关心字符是否存在,完全忽略重复出现的次数。比如你的word2 = "ANN"里的两个N,在集合视角下和一个N没有区别,所以word2.Except(word1)会返回空集合,因为N已经在word1里出现过了,自然就得不到你想要的那个多出来的N。
要解决这个问题,我们需要先统计每个字符在两个字符串中的出现次数,然后基于次数的差异来提取结果。下面是具体的实现方案:
解决方案:统计字符出现次数后对比差异
using System; using System.Linq; using System.Collections.Generic; public class Program { public static void Main(string[] args) { string word1 = "AN"; string word2 = "ANN"; // 统计每个字符串中字符的出现次数 var charCount1 = word1.GroupBy(c => c) .ToDictionary(group => group.Key, group => group.Count()); var charCount2 = word2.GroupBy(c => c) .ToDictionary(group => group.Key, group => group.Count()); // 获取两个字符串中所有出现过的字符 var allUniqueChars = charCount1.Keys.Union(charCount2.Keys); // 提取差异字符:根据两个字符串中字符的次数差生成结果 var diffCharacters = allUniqueChars.SelectMany(key => { // 获取当前字符在两个字符串中的出现次数,不存在则为0 int countInWord1 = charCount1.TryGetValue(key, out int c1) ? c1 : 0; int countInWord2 = charCount2.TryGetValue(key, out int c2) ? c2 : 0; // 计算次数差,取绝对值(如果需要双向差异) int difference = Math.Abs(countInWord1 - countInWord2); // 生成对应次数的字符序列 return Enumerable.Repeat(key, difference); }); // 输出结果,这里会得到单个字符 'N' foreach (var c in diffCharacters) { Console.WriteLine(c); } } }
代码解释:
- 统计字符次数:用
GroupBy把每个字符按自身分组,再通过ToDictionary将字符映射到它的出现次数,这样我们就得到了每个字符在字符串里的计数。 - 获取所有字符:通过
Union获取两个字符串中出现过的所有唯一字符,避免遗漏任何可能有差异的字符。 - 生成差异序列:遍历每个唯一字符,计算它在两个字符串中的次数差,用
Enumerable.Repeat生成对应次数的字符,最后用SelectMany把所有差异字符合并成一个连续的序列。
按需调整:只获取某一方多出来的字符
如果你只需要获取word2比word1多的字符(而不是双向差异),可以修改差异计算的逻辑:
var diffCharacters = allUniqueChars.SelectMany(key => { int countInWord1 = charCount1.TryGetValue(key, out int c1) ? c1 : 0; int countInWord2 = charCount2.TryGetValue(key, out int c2) ? c2 : 0; // 只保留word2中次数更多的部分 int excessCount = countInWord2 - countInWord1; return excessCount > 0 ? Enumerable.Repeat(key, excessCount) : Enumerable.Empty<char>(); });
这样就只会返回word2中比word1多的那个N,完全符合你的预期结果。
内容的提问来源于stack exchange,提问作者NoviceMe
相关产品推荐
相关产品推荐

