输入一个整数数组,数组中只有一个数字出现M次,其他数字都出现N次。请找出那个唯一的出现M次的数字。假设M不能被N整除。 使用cpp

#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 次的数字。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值