寻找数组中只出现一次的数字,一共两个。
思路
先思考怎么在一个数组中找到只出现一次的一个数字。 用异或的方法。一个数异或它本身为0,那么对数组中所有的数字都异或,相同的数字抵消,剩下的就是所求的数。
再考虑把数组分离成两个,每个数组各有一个只出现一次的一个数字。把这个数组的所有数字异或后的结果为所求的两个数字的异或,这个数字肯定不为0,取最低不为0的一位作为标准,分离数组,不可能出现数字相同的两个数字在不同小组。同时把所求的两个数字也分离了。(就是因为它们二进制某一位不同,异或后这一位才不同)
代码:
bool IsBit1(int num, int indexBit) //判断某一位是否是1
{
num = num >> indexBit;
return (num & 1);
}
int FindFirstBitIs1(int num) //找到最低位的1
{
int indexBit = 0;
while ((num & 1) == 0 && (indexBit < 8 * sizeof(int)))
{
num = num >> 1;
indexBit++;
}
return indexBit;
}
void FindNumsAppearOnce(int data[], int len, int* num1, int* num2)
{
if (data == NULL || len <= 0)
return;
int resultOR = 0;
for (int i = 0; i < len; i ++)
{
resultOR ^= data[i];
}
int indexOf1 = FindFirstBitIs1(resultOR);
*num1 = 0;
*num2 = 0;
for (int j = 0; j < len; j++)
{
if (IsBit1(data[j], indexOf1))
(*num1)= (*num1) ^ data[j];
else
(*num2) = (*num2) ^ data[j];
}
}
倒置句子的单词顺序,左旋数组
思路:
倒置整个字符串,再分别倒置整个单词。左旋数组也是整个思路。
代码:
void MyReverse(char* pbegin, char* pend)
{
if (pbegin == NULL || pend == NULL)
{
return;
}
while (pbegin < pend)
{
char temp = *pbegin;
*pbegin = *pend;
*pend = temp;
pbegin++;
pend--;
}
}
char* ReverseWord(char* pdata)
{
if (*pdata == NULL)
{
return NULL;
}
char* pbegin =pdata;
char* pend = pdata;
while (*pend != ' ')
pend++;
pend--;
MyReverse(pbegin, pend);
pend = pdata;
pbegin = pdata;
while (*pbegin != ' ') //反转每个单词
{
if (*pbegin == ' ') //一个单词结束
{
pbegin++;
pend++;
}
else if (*pend == ' ' || *pend == ' ') //找到一个单词
{
MyReverse(pbegin, --pend);
pbegin = ++pend;
}
else //pend没有读取到一个单词的末尾;
{
pend++;
}
}
return pdata;
}
char* LeftRotateString(char* pdata,int n)
{
if (pdata == NULL)
return NULL;
int len = strlen(pdata);
if (len > 0 && n > 0 && n < len)
{
char* pbegin = pdata;
char* pend = pdata + len - 1;
MyReverse(pbegin, pend);
pbegin = pend;
pbegin = pend - n + 1;
MyReverse(pbegin, pend);
pend = pbegin - 1;
pbegin = pdata;
MyReverse(pbegin, pend);
}
return pdata;
}