#include <iostream>
#include <stdio.h>
#include <bitset>
#include <vector>
using namespace std;
/*
问题:数组A包含0到n的所有整数,但其中缺了一个。在这个问题中,只用一次操作无法取得数组A里某个整数的完整内容。
此外,数组A的元素皆以二进制表示,唯一可用的访问操作是“从A[i]取出第j位数据”,该操作的时间复杂度为长度。
请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
分析:
书上解法:通过分析最低有效位(若指定最低有效位为1,则表明每个整数的最后一位上的数字)中1和0的数字结果来确定。
参见。程序员面试金典:P172页。
假设: 0000, 0001, 0010
观察发现:如果n为奇数,则在最低有效位为1时,count(0)=count(1);n为偶数,count(0) = count(1) + 1
规律: count(0) >= count(1)
如果除去丢失的整数,统计的某最低有效位: count(0) <= count(1),则说明该丢失的整数的该最低有效位应该为0
count(0) > count(1), 则说明 1
再做下一次处理时,将数组中最低有效位与计算出实际有效位不等的整数全部排除,用剩下的整数进行下一个有效位
的计算
输入:
6(0到n中的n,接下来给出n个元素)
00000 00001 00010 00100 00101 00110(n个元素)
输出:
3
关键:
1 通过分析最低有效位(若指定最低有效位为1,则表明每个整数的最后一位上的数字)中1和0的数字结果来确定。
假设: 0000, 0001, 0010
观察发现:如果n为奇数,则在最低有效位为1时,count(0)=count(1);n为偶数,count(0) = count(1) + 1
规律: count(0) >= count(1)
如果除去丢失的整数,统计的某最低有效位: count(0) <= count(1),则说明该丢失的整数的该最低有效位应该为0
count(0) > count(1), 则说明 1
再做下一次处理时,将数组中最低有效位与计算出实际有效位不等的整数全部排除,用剩下的整数进行下一个有效位
的计算
2 bitset是一个bit对象,而不是一群bit对象
bitset<32> bitesetNum(value);//设定bit最长长度为32位,并用字符串初始化比特对象
3 //如果为空,直接返回0,必须返回0,否则递归的结果用于左移会有问题
if( vecBitset.empty() )
{
return 0;
}
//说明丢失整数的第coulumn位为0,则只保留当前位为0的所有整数
if(count0 <= count1)
{
int v = findLostNumber(vecZeros , column + 1 , columnMax);
return (v << 1) | 0; // 插入当前结果最低有效位为0
}
*/
//除了传入需要计算的biset集合外,还需要传入当前处理的是第几位的比特
int findLostNumber(vector< bitset<32> >& vecBitset , int column , int columnMax)
{
//如果为空,直接返回0,必须返回0,否则递归的结果用于左移会有问题
if( vecBitset.empty() )
{
return 0;
}
if(column >= columnMax)
{
return 0;
}
vector< bitset<32> >::iterator it;
vector< bitset<32> > vecOnes;
vector< bitset<32> > vecZeros;
for(it = vecBitset.begin() ; it != vecBitset.end(); it++)
{
bitset<32> bitsetNum = *it;
//统计当前第i位为0或1
int value = bitsetNum[column];
if(value == 1)
{
vecOnes.push_back(bitsetNum);
}
else
{
vecZeros.push_back(bitsetNum);
}
}
int count0 = vecZeros.size();
int count1 = vecOnes.size();
//说明丢失整数的第coulumn位为0,则只保留当前位为0的所有整数
if(count0 <= count1)
{
int v = findLostNumber(vecZeros , column + 1 , columnMax);
return (v << 1) | 0; // 插入当前结果最低有效位为0
}
else
{
int v = findLostNumber(vecOnes , column + 1 , columnMax);
return (v << 1) | 1;
}
}
void process()
{
int n;
string value;
vector< bitset<32> > vecBitset;
while(cin >> n)
{
for(int i = 0 ; i < n ; i++)
{
cin >> value;
bitset<32> bitesetNum(value);//设定bit最长长度为32位,并用字符串初始化比特对象
vecBitset.push_back(bitesetNum);
}
//
int result = findLostNumber(vecBitset , 0 , 32);
cout << result << endl;
}
}
int main(int argc, char* argv[])
{
process();
getchar();
return 0;
}
程序员面试金典: 9.5位操作 5.7寻找丢失的整数
最新推荐文章于 2022-07-18 23:03:16 发布