PAT甲级 A1001. A+B Format (20)

1001 A+B Format (20分)

Calculate a+b and output the sum in standard format – that is, the digits must be separated into groups of three by commas (unless there are less than four digits).

Input Specification:

Each input file contains one test case. Each case contains a pair of integers a and b where −106≤a,b≤106. The numbers are separated by a space.

Output Specification:

For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format.

Sample Input:

-1000000 9

Sample Output:

-999,991

我的提交

#include<iostream>
#include<string>
#include<vector>
#include<math.h>
using namespace std;
int main() {
    int a, b;
    cin >> a >> b;
    int t = a + b;
    if (t == 0) {
        cout << "0";
        return 0;
    }
    if (t < 0) {
        cout << "-";
        t = -t;
    }

    //to string
    vector<int> s;
    int maxN = (int)log10(t);
    for (int i = maxN; i >= 0; i--) {
        int n = t % (int)(pow(10, i + 1)) / (int)(pow(10, i));
        s.push_back(n);
    }

   

    //output
    int N = s.size();
    for (int i = 0; i < N; i++)
    {
        cout << s[i];
        if ((N - 1 - i) % 3 == 0) {
            if (i != N - 1) {
                cout << ",";
            }
        }
	}


    return 0;
}

大致思路

主要思路是,将输出结果转化为字符串,然后字符串输出的时候兼顾一下格式。

但是因为没有掌握string转化,采用了动态int数组来替代string。

输入+异常检测部分

输入很简单。

异常检测首先是对于正负号的判断。

用示例就会发现,负号很影响后续判断数字大小,首先将负号去除。

最后,在后期提交的时候,发现0也有点问题,直接提前去除。

转str部分

要将每一位数字提取出来,也就是每10的倍数一位。

第一次尝试代码为:

if (t > 1000000) {
    int n1 = t / 1000000;
    int n2 = (t / 1000) % 1000;
    int n3 = t % 1000;
    cout << n1 << "," << n2 << "," << n3;
}
else if (t > 1000) {
    cout << t / 1000 << "," << t % 1000;
}
else {
    cout << t;
}

通过查找规律发现每次都是先除以一个10的倍数,再整除一个10的倍数,整理可得:

vector<int> s;
int n3 = t % (int)(pow(10, 3)) / (int)(pow(10, 2));
s.push_back(n3);
int n2 = t % (int)(pow(10, 2)) / (int)(pow(10, 1));
s.push_back(n2);
int n1 = t % (int)(pow(10, 1)) / (int)(pow(10, 0));
s.push_back(n1);

再转化为for循环就很简单了。

cout部分

难点在于怎么找到“,”应该输出的位数。

可以先写一些例子试试,比如:(为方便计算,这里的数字直接表示数组下标,所以开头是0)

0,123
01,234
012,345
0,123,456

可以看到有规律的应该是从后往前,也就是【最后一位】减【当前位数】,代码里就是(N-1)-i

(N-1)-i再写一下例子试试

3,210
43,210
543,210
6,543,210

这次很明显是在每个3的倍数后面有一个逗号了。

所以就是当(N - 1 - i) % 3 == 0的时候,后面应该再加一个逗号。

如果只是判定这个,经过简单的自测,会很快发现输出结果出现了123,这种情况(。)

也就是没有去除结尾,就再加一句判定结尾i != N - 1

※新知识※

跑去看了柳神博客.1001,题解超级简单,一个函数转string!!!

柳神题解
#include <iostream>
using namespace std;
int main() {
    int a, b;
    cin >> a >> b;
    string s = to_string(a + b);
    int len = s.length();
    for (int i = 0; i < len; i++) {
        cout << s[i];
        if (s[i] == '-') continue;
        if ((i + 1) % 3 == len % 3 && i != len - 1) cout << ",";
    }
    return 0;
}
int转string函数
string s = to_string(int num);
调试技巧
查看未知函数参数or返回值

有一些函数忘记了,想尝试一下功能和参数等等……

可以在main函数的开头试一下输出,比如试试pow()

int main() {
	cout << pow(10, 2) << endl;
    //...
}
注意测试 边界值or特殊解

要多尝试一下特殊解,自测一下。

比如这道题中的“0”就很容易错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值