问题描述
给定两个二进制字符串,返回他们的和(用十进制字符串表示)。输入为非空字符串且只包含数字 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);
}
}