剑指offer-字符串转为int数字,不用+来相加两个数,不用新增变量来交换数,在递增序列中找和为s的两个数字and找和为s的序列。 字符串转为int数字 不用+来相加两个数 PS.不用新增变量来交换数 在递增序列中找和为s的两个数字and找和为s的序列。
思路:
思路不难,但又很多注意的地方,如输入的字符串为"",为空指针。字符串符号问题,字符串有非法字母。数据溢出。
代码:
static bool Invalid = 0;
#define MaxInt 0x7FFFFFFF
#define MinInt 0x80000000
long StringtoLong(char* str,bool flag)
{
long num = 0;
while (*str != ' ')
{
if (*str >= '0' && *str <= '9')
{
num = num * 10 + *str - '0';
str++;
}
else
{
Invalid = true;
return 0;
}
}
cout << num << ' ';
if (flag == 1)
num = -num;
if (num < (int)MinInt) //这里的num是long类型,0x8000000要转为int类型,否则,long的0x8000000为正数。
{
Invalid = 1;
return 0;
}
else if (num > MaxInt)
{
Invalid = 1;
return 0;
}
return num;
}
int StringtoInt(char* str)
{
bool flag = 0;
if (str == NULL)
{
Invalid = 1;
return 0;
}
if (*str == ' ')
{
Invalid = 1;
return 0;
}
if (*str == '+')
{
flag = 0;
str++;
}
else if (*str == '-')
{
flag = 1;
str++;
}
/*for (; *str != ' '; str++)
{
cout << *str;
}*/
long ans = StringtoLong(str,flag);
return (int)ans;
}
不用+来相加两个数
思路:
考察位操作。二进制中。第n位相加,都是1的话,结果为0,进位为0。一个为1,一个为0,结果为1,进位为0。都为0时,进位为0,结果为0.可以看到,结果为异或操作,进位为与操作。
代码:
int Add(int a, int b)
{
do//先要运行一次,因为b可能是0
{
int sum = a ^ b;
int carry = (a & b )<< 1;
a = sum;
b = carry;
} while (b != 0);
return a;
}
PS.不用新增变量来交换数
思路:
有两种,一种位运算,一种加减法。
代码:
void exchange1(int a, int b)
{
a = a + b;
b = a - b;;
a = b;
}
void exchange2(int a, int b)
{
a = a ^ b;
b = a ^ a;
a = a ^ b;
}
在递增序列中找和为s的两个数字and找和为s的序列。
思路:
递增序列,可以从两头往中间走,和小于s,前面的指针向后,大于s,后面的指针向前。
找和为s的序列也是这个思路,两个指针一开始指向第一个第二个数字,随后比较sum和s,sum<s,后指针往后,增加一个数字。反之,前指针向前,抛弃一个数字。不从从两头往中间走是因为,数组的和在一直变小。
代码:
bool find_twonumbers(int arr[], int len,int k)
{
bool found = false;
if (arr == NULL||len<=0)
return found;
int head = 0;
int tail = len - 1;
while (head < tail)
{
int sum = arr[head] + arr[tail];
if (sum == k)
{
cout << arr[head] << ' ' << arr[tail] << endl;
found = true;
break;
}
else if (sum < k)
{
head++;
}
else
{
tail--;
}
}
return found;
}
void FindContinueSequence(int sum)
{
if (sum < 3)
return;
int small = 1;
int big = 2;
int middle = (sum + 1) / 2;
int current = 3;
while (small < middle) //当small大于等于middle时,small到big的数字肯定大于sum
{
if (current == sum)
{
for (int i = small;i < big + 1; i++)
{
cout << i << ' ';
}
big++;
current += big;
cout << endl;
}
else if (current < sum)
{
big++; //加入一个大的数字
current += big;
}
else
{
current -= small;
small++; //去掉一个小的数字
}
}
}