二进制之和(困难)

57 阅读3分钟

问题描述

给定两个二进制字符串,返回他们的和(用十进制字符串表示)。输入为非空字符串且只包含数字 1 和 0 ,请考虑大数问题。时间复杂度不要超过 O(n^2),其中 n 是二进制的最大长度。

输入格式

每个样例只有一行,两个二进制字符串以英文逗号“,”分割

输出格式

输出十进制格式的两个二进制的和

输入样例

101,110

输出样例

11

数据范围

每个二进制不超过 100 个字符,JavaScript 语言下请考虑大数的情况。

问题分析

函数签名:string addBinary(const string &a, const string &b):这个函数接收两个二进制字符串,并返回它们的十进制和作为字符串。 变量初始化:string result;:用于存储二进制加法的中间和最终结果(在反转之前)。int carry = 0;:初始化进位为0。int i = a.size() - 1; 和 int j = b.size() - 1;:分别初始化两个字符串的索引,从末尾开始遍历。 循环逻辑:while (i >= 0 || j >= 0 || carry):当任一字符串还有未处理的位或存在进位时,继续循环。在循环内部,首先处理进位,然后根据索引 i 和 j 的有效性,将对应位置的字符转换为数字并加到 sum 上。更新进位 carry 和结果字符串 result。 结果处理:reverse(result.begin(), result.end());:由于是从字符串末尾开始构建结果,因此最后需要反转字符串。long long decimalSum = stoll(result, 0, 2);:将二进制字符串转换为十进制长整数。这一步实际上是多余的,因为题目要求返回的是十进制字符串,而不是长整数。return to_string(decimalSum);:将十进制长整数转换回字符串并返回。由于前面的 stoll 转换是多余的,这一步也可以优化为直接返回 result 字符串(在反转之后)。

JAVA代码

import java.util.Stack;

public class Main {

public static int solution(String expression) {

    Stack<Integer> numStack = new Stack<>();

    Stack<Character> opStack = new Stack<>();  

    // 遍历表达式

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

        char c = expression.charAt(i);

        // 如果是数字,将其转换为整数并压入数字栈

        if (Character.isDigit(c)) {

            int num = 0;

            while (i < expression.length() && Character.isDigit(expression.charAt(i))) {

                num = num * 10 + (expression.charAt(i) - '0');

                i++;

            }

            i--;

            numStack.push(num);

        }

        // 如果是左括号,直接压入运算符栈

        else if (c == '(') {

            opStack.push(c);

        }

        // 如果是右括号,进行计算直到遇到左括号

        else if (c == ')') {

            while (opStack.peek() != '(') {

                char op = opStack.pop();

                int num2 = numStack.pop();

                int num1 = numStack.pop();



                if (op == '+') {

                    numStack.push(num1 + num2);

                } else if (op == '-') {

                    numStack.push(num1 - num2);

                } else if (op == '*') {

                    numStack.push(num1 * num2);

                } else if (op == '/') {

                    numStack.push(num1 / num2);

                }

            }

            opStack.pop();

        }

        // 如果是运算符,根据优先级进行处理

        else if (isOperator(c)) {

            while (!opStack.isEmpty() && precedence(c) <= precedence(opStack.peek())) {

                char op = opStack.pop();

                int num2 = numStack.pop();

                int num1 = numStack.pop();

                  if (op == '+') {

                    numStack.push(num1 + num2);

                } else if (op == '-') {

                    numStack.push(num1 - num2);

                } else if (op == '*') {

                    numStack.push(num1 * num2);

                } else if (op == '/') {

                    numStack.push(num1 / num2);

                }

            }

            opStack.push(c);

        }

    }


    // 处理剩余的运算符

    while (!opStack.isEmpty()) {

        char op = opStack.pop();

        int num2 = numStack.pop();

        int num1 = numStack.pop();

        if (op == '+') {

            numStack.push(num1 + num2);

        } else if (op == '-') {

            numStack.push(num1 - num2);

        } else if (op == '*') {

            numStack.push(num1 * num2);

        } else if (op == '/') {

            numStack.push(num1 / num2);

        }

    }

      // 返回数字栈的栈顶元素即为结果

    return numStack.pop();

}


// 判断是否为运算符

public static boolean isOperator(char c) {

    return c == '+' || c == '-' || c == '*' || c == '/';

}


// 定义运算符的优先级

public static int precedence(char op) {

    if (op == '+' || op == '-') {

        return 1;

    } else if (op == '*' || op == '/') {

        return 2;

    }

    return -1;

}

  public static void main(String[] args) {

    // You can add more test cases here

    System.out.println(solution("1+1") == 2);

    System.out.println(solution("3+4*5/(3+2)") == 7);

    System.out.println(solution("4+2*5-2/1") == 12);

    System.out.println(solution("(1+(4+5+2)-3)+(6+8)") == 23);

}

}