杭电 OJ-ACM1002 (A+B Problem Ⅱ)

题干——

Problem Description

我有一个非常简单的问题要给你。给定两个整数A和B,你的工作是计算A + B的和。

Input

输入的第一行包含一个整数T(1<=T<=20),它表示测试用例的数量。然后是T行,每行由两个正整数组成,A和b。注意,这些整数非常大,这意味着你不应该使用32位整数来处理它们。您可以假设每个整数的长度不会超过1000。

     注:依最后两句的提示知,系统输入的数字不仅会超过int的最大值,连long也无法容纳!所以我们不能用传统的定义int或long再通过相加得出结果.

Output

对于每个测试用例,您应该输出两行。第一行是“Case#:”,#表示测试用例的数量。第二行是一个方程“A+B=Sum”,和表示A + B的结果。注意,在这个方程上有一些空间。在两个测试用例之间输出一条空行。

 法1:

     分析:我们既然不能用纯数字来解决,我们可以通过将输入的各个数位改为字符常量然后一一存入数组,以便于后续两者相加.

    ⒈.先搭好整体框架,再输入字符串变量

     

import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner k = new Scanner(System.in);
        String strA, strB;
        int[] a = new int[1000];
        int[] b = new int[1000];
        strA = k.next();
        strB = k.next();

⒉.对于strA和strB的数据进行一一提取(单个字符常量)并存入a[] 和b[]数组中

import java.util.Scanner;

public class Main{
    public static void main(String args[]) {
        Scanner k = new Scanner(System.in);
        String strA, strB;
        int[] a = new int[1000];
        int[] b = new int[1000];
        char m, n;
        int sum;
        strA = k.next();
        strB = k.next();
        for (int i = 0; i < strA.length(); i++) {
            m = strA.charAt(i);
            a[i] = (int) m - (int) ('0');
        }
        for (int i = 0; i < strB.length(); i++) {
            n = strB.charAt(i);
            b[i] = (int) n - (int) ('0');
        } 

    在对于字符串变量提取字符变量,再转换为整形数组时,可采取ASCII码的转换;用(int)强制转换符号将提取出来的char字符变量换为int(PS:注意(int)0单引号

      (☆☆☆)但是,必须注意一个问题,数组的第一个下标为0,而不是1,故必须写成诸如

for (int i = 0; i < strA.length(); i++)

的形式,即i=0对应a[0] ,第一个数组对应的下标一定为0!

⒊.我们接下来就是至关重要的相加,顾名思义,利用存储数组的思想就是巧妙地运用竖式求和的方式!但是我们不得不思考到一个问题,若两者数字长度不一致,在竖式求和时必然会存在问题,所以我们应当比较两者的数字长度大小.在这里我们可以采用<字符串变量>.length();提取长度.

            if (strA.length() < strB.length()) {
            sum = strB.length();
            for (int i = strA.length() - 1; i >= 0; i--) {
                a[i + sum - strA.length()] = a[i];
            }
            for (int i = 0; i < sum - strA.length(); i++) {
                a[i] = 0;
            }
        }
        else {
            sum = strA.length();
            for (int i = strB.length() - 1; i >= 0; i--) {
                b[i + sum - strB.length()] = b[i];
            }
            for (int i = 0; i < sum - strB.length(); i++) {
                b[i] = 0;
            }
        }

  当比较出两者的相对大小后,由竖式的相加原理,我们应当在位数较小的数字前面补“0”使得两个数组长度一致,才能进行最终的计算.同时我们定义俩数组的最大值为sum,来实现定义补“0”位数的下标和后续的相加总位数.

⒋.我们可以通过定义t来实现进位功能:从最后一项逐渐往前,当每一次的数值和大于或等于10应当减去10,而前一个项相加时会进1,而因为是两位相加绝不会出现进两位的情况,故只需t=1即可;当没有超过10时立即将t改为0.

 int t=0;
        for (int i=sum-1;i>=0;i--){
            c[i]=a[i]+b[i]+t;
            if (c[i]>=10){
                c[i]=c[i]-10;
                t=1;
            }
            else {
                t=0;
            }

⒌.最终实现输出时应当注意,因为c[i]是数组,我们应当逐一输出且不能换行;而在最后一个数组输出时必须换行两次

for (int i = 0; i < sum; i++) {
                    if (i < sum - 1) {
                        System.out.printf("%d", c[i]);
                    }
                    else {
                        System.out.printf("%d\n", c[i]);
                        System.out.println();
                    }

⒍.在整体思路通过代码实现后,我们再对细枝末节进行润色,如输入的次数,Case#: ,#的数字以及包含的空格等等!

    最终成品为——

import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner k = new Scanner(System.in);
        String strA, strB;
        int[] a = new int[1000];
        int[] b = new int[1000];
        int[] c = new int[1000];
        char m, n;
        int sum, N, num;
        N = k.nextInt();
        num = N;//总次数
        while (N > 0) {//输出N此
            strA = k.next();
            strB = k.next();
            for (int i = 0; i < strA.length(); i++) {
                m = strA.charAt(i);
                a[i] = (int) m - (int) ('0');
            }
            for (int i = 0; i < strB.length(); i++) {//从i=0开始取第一个
                n = strB.charAt(i);
                b[i] = (int) n - (int) ('0');
            }
            if (strA.length() < strB.length()) {
                sum = strB.length();//最大的字符串位数
                for (int i = strA.length() - 1; i >= 0; i--) {
                    a[i + sum - strA.length()] = a[i];//前方补“0”
                }
                for (int i = 0; i < sum - strA.length(); i++) {
                    a[i] = 0;
                }
            } else {
                sum = strA.length();
                for (int i = strB.length() - 1; i >= 0; i--) {
                    b[i + sum - strB.length()] = b[i];
                }
                for (int i = 0; i < sum - strB.length(); i++) {
                    b[i] = 0;
                }
            }
            int t = 0;
            for (int i = sum - 1; i >= 0; i--) {
                c[i] = a[i] + b[i] + t;
                if (c[i] >= 10) {//实现进位
                    c[i] = c[i] - 10;
                    t = 1;
                } else {
                    t = 0;
                }
            }
            System.out.printf("Case %d:\n", num - N + 1);//输出Case#:且计算出#的大小
            System.out.printf("%s + %s = ", strA, strB);
            for (int i = 0; i < sum; i++) {
                    if (i < sum - 1) {
                        System.out.printf("%d", c[i]);//逐一输出
                    }
                    else {
                        System.out.printf("%d\n", c[i]);
                        System.out.println();//最后一位连换两行
                    }
                N--;
            }
        }
    }
}

 法2:

    当int甚至long无法满足取值范围时,我们可以通过引入超大整数类BigInteger最大程度地满足取值范围。

    同Scanner相同,BigInteger同样是来自于某头文件的,我们在顶部应当输入如下语句——

import java.math.BigInteger;

  同理,我们能够通过下列语句来定义变量;

 BigInteger sum;

  能够通过下列语句来实现键盘输入.

BigInteger A = k.nextBigInteger();
BigInteger B = k.nextBigInteger();

 对于BigInteger,我们有以下多种功能实现:

1.字符串转数字

String str="..."
BigInteger sum=new BigInteger(str);//先前未定义sum及其数据类型

或

BigInteger sum=new BigInteger("...");

2.运算

BigInteger a = new BigInteger("99999999999999999");
BigInteger b = new BigInteger("99999999999999999");
 
BigInteger add = a.add(b);// 加法
 
BigInteger subtract = a.subtract(b); // 减法
 
BigInteger multiply = a.multiply(b); // 乘法
 
BigInteger divide = a.divide(b); // 除法(*选学)
 
BigInteger mod = a.mod(b); // 取余(只返回正数)(*选学)
 
(*选学)BigInteger remainder = a.remainder(b); // 取余(正负数都有可能返回)
// 求商和余数
(*选学)BigInteger[] bigIntegers = a.divideAndRemainder(b); // 返回一个BigInteger数组,
// bigIntegers[0]是a/b的商,bigIntegersp[1]是a%b的余
(*选学)System.out.println(bigIntegers[0]+" "+bigIntegers[1]); // 1 0(商1,余0)

综上,最终成品为——

import java.util.Scanner;
import java.math.BigInteger;
public class Main1002_2 {
    public static void main(String args[]) {
        Scanner k = new Scanner(System.in);
        String str,strA,strB;
        int N;
        BigInteger sum;
        N = k.nextInt();
        int num=N;
        while(N>0) {
            BigInteger A = k.nextBigInteger();
            BigInteger B = k.nextBigInteger();
            sum = A.add(B);
            str = sum.toString();
            strA = A.toString();
            strB = B.toString();
            System.out.println("Case "+(num-N+1)+":");
            if (N != 1) {
                System.out.println(strA+" + "+strB+" = "+str);
                System.out.println();
            }
            else {
                System.out.println(strA+" + "+strB+" = "+str);
                }
                N--;
            }
        }
    }

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值