如何查找128位BitArray数组中的重复元素?附尝试代码
查找128位BitArray数组中的重复元素
嘿,我看到你正在处理128位BitArray的重复元素检测,先帮你把未完成的代码补全,同时优化一下实现逻辑~
首先,你的核心思路是对的:BitArray默认是引用类型,直接比较会看引用而非内容,所以必须先把每个BitArray转换成能代表其内容的字符串(或其他值类型),再统计重复。
第一步:实现可靠的BitArray转字符串方法
你用到了BitArrayToStr但没给出实现,这里提供两种转换方式,选一种适合你的:
方式1:转成二进制字符串(直观,128字符)
private static string BitArrayToBinaryStr(BitArray bitArray) { if (bitArray.Length != 128) throw new ArgumentException("仅支持128位BitArray"); char[] chars = new char[128]; // 从高位到低位输出,保持BitArray的位顺序一致性 for (int i = 0; i < 128; i++) { chars[i] = bitArray[127 - i] ? '1' : '0'; } return new string(chars); }
方式2:转成十六进制字符串(更紧凑,32字符,效率更高)
128位刚好是16个字节,转成十六进制字符串更节省内存,统计时也更快:
private static string BitArrayToHexStr(BitArray bitArray) { if (bitArray.Length != 128) throw new ArgumentException("仅支持128位BitArray"); byte[] bytes = new byte[16]; bitArray.CopyTo(bytes, 0); // 注意字节顺序,根据你的BitArray存储需求调整是否反转 return BitConverter.ToString(bytes).Replace("-", "").ToUpper(); }
第二步:补全并优化你的重复检测代码
方法A:用LINQ的GroupBy(简洁直观)
这是你一开始用的方式,补全后可以直接获取重复元素及其出现次数:
// 先把所有BitArray转成字符串 var bitArrayStrs = final.Select(ba => BitArrayToHexStr(ba)).ToList(); // 获取所有重复元素及其出现次数 var duplicatesWithCount = bitArrayStrs .GroupBy(s => s) .Where(g => g.Count() > 1) .ToDictionary(g => g.Key, g => g.Count()); // 判断是否存在重复 bool hasDuplicates = duplicatesWithCount.Any(); // 输出结果 if (hasDuplicates) { Console.WriteLine("找到重复元素:"); foreach (var kvp in duplicatesWithCount) { Console.WriteLine($"元素: {kvp.Key},出现次数: {kvp.Value}"); } } else { Console.WriteLine("无重复元素"); }
方法B:用Dictionary手动统计(性能更优,适合大数据量)
你的代码写到一半,这里补全并优化:
var countDict = new Dictionary<string, int>(final.Length); bool hasDuplicates = false; foreach (var ba in final) { string key = BitArrayToHexStr(ba); if (countDict.TryGetValue(key, out int count)) { countDict[key] = count + 1; // 一旦发现重复可以提前标记,不用等遍历完 if (!hasDuplicates) hasDuplicates = true; } else { countDict.Add(key, 1); } } // 提取所有重复元素 var duplicateKeys = countDict.Where(kvp => kvp.Value > 1).Select(kvp => kvp.Key).ToList(); // 后续逻辑 if (hasDuplicates) { // 处理重复元素 }
额外优化建议
如果你的BitArray数量非常大,转字符串可能会有性能开销,还可以自定义一个IEqualityComparer<BitArray>,直接比较BitArray的内容,这样就不用转字符串了:
public class BitArrayEqualityComparer : IEqualityComparer<BitArray> { public bool Equals(BitArray x, BitArray y) { if (x.Length != y.Length) return false; for (int i = 0; i < x.Length; i++) { if (x[i] != y[i]) return false; } return true; } public int GetHashCode(BitArray obj) { int hash = 17; // 对128位分块计算哈希,避免溢出 for (int i = 0; i < obj.Length; i += 32) { int blockHash = 0; for (int j = 0; j < 32 && i + j < obj.Length; j++) { blockHash = blockHash * 2 + (obj[i + j] ? 1 : 0); } hash = hash * 31 + blockHash; } return hash; } }
然后直接用这个比较器来统计:
var duplicates = final .GroupBy(ba => ba, new BitArrayEqualityComparer()) .Where(g => g.Count() > 1) .Select(g => g.Key);
这种方式省去了字符串转换的步骤,性能会更好。
内容的提问来源于stack exchange,提问作者Yussra
相关产品推荐
相关产品推荐

