字符串中数字子串的求和

题目:

给定一个字符串str,求其中全部数字串所代表的数字之和。

要求:

忽略小数点字符,如"A1.3",其中包含两个数字1和3;

如果紧贴数字子川的左侧出现字符"-",当连续出现的数量为奇数时,则数字视为负,偶数时,则数字视为正。如"A-1BC--12",其中包含数字为-1和12。

举例:

str="A1CD2E33",返回36;

str="A-1B--2C--D6E",返回7。

难度:

思路:(考虑问题不全面)

以前对于这种题目,惯用方法是嵌套循环,这样虽然也能实现,但时间复杂度就是O(n^2)数量级的,达不到练习的目的。

对于这种题目,对整个字符串进行遍历,在遍历的过程中对每个字符进行相应处理。

在循环遍历中,我分成三种情况讨论,一种是数字字符,一种是'-'字符,一种是其他情形;并对不同的情形做不同处理。

若是数字字符,对其进行数字识别;若是'-'字符,则对符号位取反;若是其他情形,则根据符号位决定数字的正负,将其累加,并将符号位和数字变量置零。

代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{	
	string str;
	getline(cin, str);
	int len = str.size();
	int i, sum = 0, num = 0, flag = 0;
	for (i = 0; i < len; i++)
	{
		if (str[i] == '-')
			flag = 1 - flag;
		else if (isdigit(str[i]))
			num = num * 10 + str[i] - '0';
		else
		{
			if (flag)
				num = -num;
			sum += num;
			flag = 0;
			num = 0;
		}
	}
	cout << sum << endl;
	system("pause");
	return 0;
}

本以为我考虑的比较全面了,但是查阅书本上的讲解,发现其实有很多疏漏。

如"-1-2-3",应该返回-6,但程序给出的结果是0。这就是没有考虑到'-'字符也是作为数字识别结束的标志;

而且对于边界问题,考虑的也不全面。So, this is not a good solution......

参考思路:

对字符串进行遍历,判断每个字符是数字字符还是非数字字符。

如果是数字字符,更新数字变量;如果是非数字字符,首先判断符号标志位确定正负,再累加,对数字变量置零;并判断给非数字字符是否为'-',如果该位字符是'-',则判断前一个字符是否也是'-',如果前一个是'-',则对符号标志位取反;若不是,则对符号标志位置一;如果该位字符不是‘-’,对符号标志位置零。

注意,对于最后一位是数字,则需要对其进行单独考虑。

参考代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string str;
	getline(cin, str);
	int len = str.size();
	int i, num = 0, sum = 0, flag = 0;    // num为当前收集到的数字,sum为目前累加和,flag为当前收集到的数字是正是负
	for (i = 0; i < len; i++)
	{
		if (isdigit(str[i]))
		{
			num = num * 10 + str[i] - '0';
			if (i == len - 1)
			{
				if (flag)
					num = -num;
				sum += num;
			}
		}
		else
		{
			if (flag)
				num = -num;
			sum += num;
			num = 0;
			if (str[i] == '-')
			{
				if (i - 1 >= 0 && str[i - 1] == '-')    // 当前位是'-',判断前一位是否为'-'
					flag = 1 - flag;
				else
					flag = 1;
			}
			else
				flag = 0;
		}
	}
	cout << sum << endl;
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值