- Interview Questions
- /
- Problems
- /
- Basic Calculator II
Basic Calculator II
Evaluate an arithmetic string with +, -, * and / using normal precedence, without eval. Tests whether you can handle operator precedence in a single left-to-right pass. Solve it below in Python or JavaScript, then read the walkthrough.
Problem
You're given a string s containing a valid arithmetic expression. It is made of non-negative integers, the operators +, -, * and /, and any number of spaces. There are no parentheses and no unary minus signs.
Evaluate it with the usual precedence: * and / bind tighter than + and -, and operators of the same precedence are applied left to right. Integer division truncates toward zero, so 7 / 2 is 3 and -7 / 2 is -3.
Return the result as an integer. Don't use a built-in expression evaluator such as eval.
Example 1
- Input
- s = "4+6*2"
- Output
- 16
Multiplication first: 6 * 2 = 12, then 4 + 12 = 16.
Example 2
- Input
- s = " 20 / 3 - 1 "
- Output
- 5
20 / 3 truncates to 6, and 6 - 1 = 5. Spaces are ignored.
Example 3
- Input
- s = "9-8/4*3"
- Output
- 3
8 / 4 = 2, then 2 * 3 = 6, and 9 - 6 = 3.
Constraints
- 1 ≤ s.length ≤ 3 × 10⁵
- s contains digits, spaces, and the characters + - * /
- Every number is in the range [0, 2³¹ - 1], and no division is by zero.
- Every intermediate result and the final answer fit in a 32-bit signed integer.
Practice
Runs 15 tests in your browser. Python loads on the first run (about 6 MB, then cached). Press ⌘/Ctrl + Enter to run.
Get asked Basic Calculator II in a real interview?
Interview Solver gives you a working solution live, during your actual coding interview. Invisible to screensharing.
How to solve Basic Calculator II
Pattern: Running term with deferred addition
Without parentheses, an expression is a sum of terms, where each term is a run of numbers joined by * and /. For 9-8/4*3 the terms are +9 and -(8/4*3).
So read left to right and keep the term you're still building separately from the total. A number after + or - starts a new term (with that sign), which means the previous term is finished and can be added to the total. A number after * or / folds into the current term right away. Because you always know the operator before a number, you only ever need to remember one pending operator.
A stack works too: push each signed term and fold * / / into the top. The running-term version is the same idea with the stack collapsed into two variables, since only the top is ever touched.
Approach 1: Tokenize, then two passes
Split the string into numbers and operators. In the first pass, collapse every * and / into a single value. In the second pass, apply + and - left to right. Easy to get right, but it builds two token lists.
Time O(n) · Space O(n)
Approach 2: Stack of signed terms
Scan once, tracking the last operator. When a number ends: push it for +, push its negation for -, and replace the top with top * num or top / num (truncated toward zero) for * and /. The answer is the sum of the stack.
Time O(n) · Space O(n)
Approach 3: One pass with a running term
Keep total = 0, term = 0, num = 0, and op = '+'. Scan each character, plus a sentinel at the end:
- Digits extend
num. Spaces are skipped. - On an operator (or the end), apply
optonum: for+/-, addtermtototaland startterm = ±num. For*, setterm *= num. For/, settermtoterm / numtruncated toward zero. - Remember the new operator in
opand resetnum = 0.
At the end, the answer is total + term.
Time O(n) · Space O(1)
| Approach | Time | Space |
|---|---|---|
| Tokenize, then two passes | O(n) | O(n) |
| Stack of signed terms | O(n) | O(n) |
| One pass with a running term | O(n) | O(1) |
Solution code
Try the practice editor first. Both solutions pass every test above.
Basic Calculator II solution in Python
def calculate(s: str) -> int:
total = 0
term = 0
num = 0
op = "+"
for i, ch in enumerate(s):
if ch.isdigit():
num = num * 10 + int(ch)
if ch in "+-*/" or i == len(s) - 1:
if op == "+":
total += term
term = num
elif op == "-":
total += term
term = -num
elif op == "*":
term *= num
else:
quotient = abs(term) // num
term = quotient if term >= 0 else -quotient
op = ch
num = 0
return total + termBasic Calculator II solution in JavaScript
function calculate(s) {
let total = 0;
let term = 0;
let num = 0;
let op = '+';
for (let i = 0; i < s.length; i++) {
const ch = s[i];
if (ch >= '0' && ch <= '9') num = num * 10 + Number(ch);
if ('+-*/'.includes(ch) || i === s.length - 1) {
if (op === '+') {
total += term;
term = num;
} else if (op === '-') {
total += term;
term = -num;
} else if (op === '*') {
term *= num;
} else {
term = Math.trunc(term / num);
}
op = ch;
num = 0;
}
}
return total + term;
}Common mistakes
- Using Python’s // for division. It floors, so -6 // 4 is -2 instead of -1. Divide the absolute values and reapply the sign, or use int(a / b).
- Only reading single-digit numbers. Build each number with num = num * 10 + digit.
- Forgetting to apply the last pending operation when the string ends. A sentinel step at the end handles it.
- Treating spaces as operators, or applying an operation when you reach a space. Only an actual operator, or the end of the string, should trigger the update.
What interviewers look for
Explain the structure before coding: "with no parentheses, it's a sum of terms, and each term is a product or quotient chain." Interviewers listen for whether you see why you only need one pending operator, instead of reaching for a full parser.
Call out truncation toward zero explicitly, and test a case where a negative term gets divided, like "1-6/4". That's the bug most Python solutions ship with.
Follow-up questions
How would you add support for parentheses?
Recurse on "(" and return on ")": evaluate the inner expression with the same loop and treat its result as a number. Iteratively, push the current total, term, and operator onto a stack at "(" and restore them at ")".
How would you support unary minus, like "-3*-2"?
A minus is unary when it appears at the start or right after another operator. Track whether you are expecting an operand; if so, flip a sign flag for the next number instead of treating "-" as a binary operator.
How would you extend this to many precedence levels, such as exponentiation?
Switch to a general technique: the shunting-yard algorithm with an operator stack, or precedence climbing, where each level parses the next-higher level as its operands. Right-associative operators like ^ just change the comparison when deciding whether to pop.
Companies that ask Basic Calculator II
Basic Calculator II is tagged by 127 companies in our interview dataset. The score shows how often it comes up at each company.
- Wizeline100%
- Elastic100%
- Danaher100%
- Delinea100%
- Highspot100%
- Rokt97.8%
- Nbc96%
- Redfin95%
- Ikea90%
- Evolutioniq90%
- Meta89.3%
- Tesla89.2%
- Reify Health89%
- Snap87.6%
- State Farm87%
- Verkada86.1%
- Vodafone84%
- Corelight83%
- Nexient82%
- Thumbtack82%
- Rivian81.1%
- Billcom81%
- Sas Software80%
- Te Connectivity80%
and 103 more.
Practice next
Get live help in the real interview
Working solutions in real time during your actual interview. Invisible to screensharing.
Start Free TrialNo credit card required