#include <iostream>
#include <vector>
// 定义一个用于查找唯一出现M次元素的类
class UniqueOccurrenceFinder {
private:
std::vector<int> nums; // 输入的数组
int M; // 目标出现次数
int N; // 其他元素出现次数
public:
// 构造函数,初始化输入数组和M、N值
UniqueOccurrenceFinder(const std::vector<int>& input, int m, int n)
: nums(input), M(m), N(n) {}
// 查找唯一出现M次的元素
int findUnique() {
std::vector<int> bitCount(32, 0); // 用于存储所有数字每一位1出现的次数
// 统计每一位上1出现的次数
for (int num : nums) {
for (int i = 0; i < 32; i++) {
bitCount[i] += (num >> i) & 1;
}
}
int result = 0;
// 根据每一位1出现的次数重建目标数字
for (int i = 0; i < 32; i++) {
int bit = bitCount[i] % N;
if (bit == M % N) { // 如果这一位是目标数字的一部分
result |= (1 << i);
}
}
return result;
}
};
// 主函数
int main() {
int size, M, N;
std::vector<int> input;
// 从用户获取输入
std::cout << "请输入数组的长度: ";
std::cin >> size;
std::cout << "请输入M (目标数字出现的次数): ";
std::cin >> M;
std::cout << "请输入N (其他数字出现的次数): ";
std::cin >> N;
if (M % N == 0) {
std::cerr << "错误:M 不能被 N 整除。" << std::endl;
return 1;
}
std::cout << "请输入数组元素(每个元素用空格分隔): ";
for (int i = 0; i < size; i++) {
int num;
std::cin >> num;
input.push_back(num);
}
// 创建UniqueOccurrenceFinder对象并执行查找
UniqueOccurrenceFinder finder(input, M, N);
int result = finder.findUnique();
// 输出结果
std::cout << "唯一出现 " << M << " 次的元素是: " << result << std::endl;
return 0;
}
bitCount[i] % N
计算的是每一位上 1 出现的次数模 N
的结果。这是因为我们知道,除了目标数字外,其余的每个数字都会出现 N
次。- 对于目标数字的每一位,其 1 的次数模
N
后的结果应该等于 M % N
。这是因为目标数字出现了 M
次,而其他数字要么出现了 N
次(模 N
结果为 0),要么出现了其他与 M
不同的次数(模 N
结果不为 M % N
)。 - 对于每一位,若
bit == M % N
,则这位是目标数字的一部分。于是,我们将该位添加到 result
中。 - 最终,
result
中的值就是唯一出现 M
次的数字。