添加存储在字符串变量中的数字

时间:2016-10-14 17:46:25

标签: java algorithm

给定两个非负数num1和num2表示为字符串,返回num1和num2之和。

num1和num2的长度均小于5100。

num1和num2都只包含数字0-9。

num1和num2都不包含任何前导零。

您不得使用任何内置BigInteger库或直接将输入转换为整数。

我尝试了我的解决方案,但它不起作用。建议?

public class Solution {
    public String addStrings(String num1, String num2) {
        double multiplier = Math.pow(10, num1.length() - 1);
        int sum = 0;

        for (int i = 0; i < num1.length(); i++){
            sum += ((((int) num1.charAt(i)) - 48) * multiplier);
            multiplier /= 10;
        }

        multiplier = Math.pow(10, num2.length() - 1);

        for (int i = 0; i < num2.length(); i++){
            sum += ((((int) num2.charAt(i)) - 48) * multiplier);
            multiplier /= 10;
        }

        return "" + sum;
    }    
}

7 个答案:

答案 0 :(得分:5)

  

您不能使用任何内置BigInteger库或直接将输入转换为整数

请注意,您要添加两个最多5100 数字的整数。这不是最大,而是最大位数

int(您的sum变量)无法保存这样的值。 BigInteger可以,但您不能使用它。

所以,像在纸上一样添加数字:添加最后一位数字,将总和的较低位写为结果的最后一位,并在需要时结转一位数。重复倒数第二位,倒数第三位等,直至完成。

由于总和至少是最长输入值的位数,并且可能长一个,因此您应该分配长度为char[]的最长输入加一。完成后,使用String(char[] value, int offset, int count)构造最终字符串,根据需要偏移量为0或1。

答案 1 :(得分:3)

此问题的目的是以字符串形式添加数字。您不应该尝试将字符串转换为整数。描述说这些数字的长度最多可达5100位。所以数字太大而不能存储在整数和双精度中。例如,在以下行中:

double multiplier = Math.pow(10, num1.length() - 1);

您正试图在double中存储10 ^ 5100。在IEEE 754 binary floating point standard中,double可以存储从±4.94065645841246544e-324±1.79769313486231570e+308的商店编号。所以你的号码不合适。它将改为Infinity。即使它适合double,它也不会准确,您在后续计算中会遇到一些错误。

因为问题指定不使用BigInteger或类似的库,所以你应该尝试自己实现字符串添加。

这非常简单,只需在纸上添加两个数字时实现您遵循的确切算法。

答案 2 :(得分:3)

以下是使用char数组作为中间容器而不使用BigInteger添加两个字符串的工作示例。 @Tempux答案解释了为什么double无法使用的要点。这里的逻辑类似于如何在纸上添加两个数字。

public String addStrings(String num1, String num2) {
    int carry = 0;
    int m = num1.length(), n = num2.length();
    int len = m < n ? n : m;
    char[] res = new char[len + 1]; // length is maxLen + 1 incase of carry in adding most significant digits
    for(int i = 0; i <= len ; i++) {
        int a = i < m ? (num1.charAt(m - i - 1) - '0') : 0;
        int b = i < n ? (num2.charAt(n - i - 1) - '0') : 0;
        res[len - i] = (char)((a + b + carry) % 10 + '0');
        carry = (a + b + carry) / 10;
    }
    return res[0] == '0' ? new String(res, 1, len) : new String(res, 0, len + 1);
}

这个片段相对较小且精确,因为在这里我没有使用不可变的String,这是复杂/混乱的并且会产生更大的代码。另外一个直觉是 - 没有办法获得比max(num1_length, num2_length) + 1更大的输出,这使得实现变得简单。

答案 3 :(得分:0)

  

你必须像在纸上一样添加

你不能使用BigInteger并且字符串长度是5100,所以你不能使用int或long来添加。 你必须像我们在纸上一样使用简单的添加。

class AddString
{
public static void main (String[] args) throws java.lang.Exception
{
    String s1 = "98799932345";
    String s2 = "99998783456";
    //long n1 = Long.parseLong(s1);
    //long n2 = Long.parseLong(s2);
    System.out.println(addStrings(s1,s2));
    //System.out.println(n1+n2);
}
public static String addStrings(String num1, String num2) {
    StringBuilder ans = new StringBuilder("");
    int n = num1.length();
    int m = num2.length();
    int carry = 0,sum;
    int i, j;
    for(i = n-1,j=m-1; i>=0&&j>=0;i--,j--){
        int a = Integer.parseInt(""+num1.charAt(i));
        int b = Integer.parseInt(""+num2.charAt(j));
        //System.out.println(a+" "+b);
        sum = carry + a + b;
        ans.append(""+(sum%10));
        carry = sum/10;
    }
    if(i>=0){
        for(;i>=0;i--){
            int a = Integer.parseInt(""+num1.charAt(i));
            sum = carry + a;
            ans.append(""+(sum%10));
            carry = sum/10;
        }
    }
    if(j>=0){
        for(;j>=0;j--){
            int a = Integer.parseInt(""+num2.charAt(j));
            sum = carry + a;
            ans.append(""+(sum%10));
            carry = sum/10;
        }
    }
    if(carry!=0)ans.append(""+carry);
    return ans.reverse().toString();
}   
}

你可以运行上面的代码并看到它在所有情况下都有效,这可以用更紧凑的方式编写,但这对你来说很难理解。

希望它有所帮助!

答案 4 :(得分:0)

你可以使用独立于Integer或BigInteger方法的那个

public String addStrings(String num1, String num2) {
    int l1 = num1.length();
    int l2 = num2.length();
    if(l1==0){
        return num2;
    }
    if(l2==0){
        return num1;
    }
    StringBuffer sb = new StringBuffer();
    int minLen = Math.min(l1, l2);
    int carry = 0;
    for(int i=0;i<minLen;i++){
        int ind = l1-i-1;
        int c1 = num1.charAt(ind)-48;
        ind = l2-i-1;
        int c2 = num2.charAt(ind)-48;
        int add = c1+c2+carry;
        carry = add/10;
        add = add%10;
        sb.append(add);
    }

    String longer = null;
    if(l1<l2){
        longer = num2;
    }
    else if(l1>l2){
        longer = num1;
    }
    if(longer!=null){
        int l = longer.length();
        for(int i=minLen;i<l;i++){
            int c1 = longer.charAt(l-i-1)-48;
            int add = c1+carry;
            carry = add/10;
            add = add%10;
            sb.append(add);
        }
    }
    return sb.reverse().toString();
}

答案 5 :(得分:-1)

为了理解问题

您的方法名称为添加

您正尝试执行电源操作,但结果存储在名为乘法的变量中...

这个代码不起作用的原因不止一个......

您需要执行类似

的操作
Integer.parseInt(string)

以便将字符串解析为整数

这里是oficial doc

答案 6 :(得分:-1)

以前的解决方案有多余的代码。这就是你所需要的一切。

class ShortStringSolution {
    static String add(String num1Str, String num2Str) {
        return Long.toString(convert(num1Str) + convert(num2Str));
    }

    static long convert(String numStr) {
        long num = 0;
        for(int i = 0; i < numStr.length(); i++) {
            num = num * 10 + (numStr.charAt(i) - '0');
        }
        return num;
    }
}

class LongStringSolution {

    static String add(String numStr1, String numStr2) {
        StringBuilder result = new StringBuilder();
        int i = numStr1.length() - 1, j = numStr2.length() - 1, carry = 0;
        while(i >= 0 || j >= 0) {
            if(i >= 0) {
                carry += numStr1.charAt(i--) - '0';
            }
            if(j >= 0) {
                carry += numStr2.charAt(j--) - '0';
            }
            if(carry > 9) {
                result.append(carry - 10);
                carry = 1;
            } else {
                result.append(carry);
                carry = 0;
            }
        }
        if(carry > 0) {
            result.append(carry);
        }
        return result.reverse().toString();
    }
}

public class Solution {

    static String add(String numStr1, String numStr2) {
        if(numStr1.length() < 19 && numStr2.length() < 19) {
            return ShortStringSolution.add(numStr1, numStr2);
        }
        return LongStringSolution.add(numStr1, numStr2);
    }
}