剑指offer-字符串转为int数字,不用+来相加两个数,不用新增变量来交换数,在递增序列中找和为s的两个数字and找和为s的序列。

字符串转为int数字

思路:

思路不难,但又很多注意的地方,如输入的字符串为"",为空指针。字符串符号问题,字符串有非法字母。数据溢出。

代码:

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++;  //去掉一个小的数字
			
		}
	}
}
原文地址:https://www.cnblogs.com/void-lambda/p/12431877.html