You are given symbol definitions in the form name=expression. An expression may contain integer constants, references to previously defined or later defined symbols, and the binary operators +, -, *, and /.
Evaluate the final integer value of every symbol. Return the results in the same order as the input definitions, formatted as "name=value".
If the dependency graph contains a cycle, return a single-element array ["CYCLE"] instead of partial results.
Function Description
Complete the function evaluateExpressionMap in the editor below.
evaluateExpressionMap has the following parameter:
String[] definitions: the symbol definitions ReturnsString[]: evaluated symbol assignments in input order, or["CYCLE"]if a cycle exists.
Constraints
1 ≤ definitions.length ≤ 10⁵- Expressions use integer arithmetic and may reference other symbols.
- Use cycle detection to avoid infinite recursion.
Example 1
Input:
definitions = ["a=1", "b=a+2", "c=b*3"]
Output:
["a=1", "b=3", "c=9"]
Explanation: Each symbol depends only on earlier evaluated values, so the map resolves cleanly.
Example 2
Input:
definitions = ["a=b+1", "b=a+1"]
Output:
["CYCLE"]
Explanation: The definitions form a cycle, so the special cycle marker is returned.
解法
把每个定义解析成「名字 → 表达式 token 序列」,然后对每个 name 做带 visiting 集合的 DFS:递归求值变量,求值过程中再次进入同一个 name 就说明有环,立即返回 CYCLE。表达式求值用经典「分两阶段:先处理 *//,再处理 +/-」或调度场算法。时间 O(N·E),E 是平均表达式长度。
from typing import List
import re
def evaluateExpressionMap(definitions: List[str]) -> List[str]:
defs: dict[str, str] = {}
order: List[str] = []
for d in definitions:
name, expr = d.split("=", 1)
defs[name.strip()] = expr.strip()
order.append(name.strip())
cache: dict[str, int] = {}
visiting: set[str] = set()
has_cycle = [False]
def evaluate(expr: str) -> int:
tokens = re.findall(r"\d+|[A-Za-z_][A-Za-z_0-9]*|[+\-*/()]", expr)
# Shunting-yard to RPN
prec = {"+": 1, "-": 1, "*": 2, "/": 2}
out: List[str] = []
ops: List[str] = []
for t in tokens:
if t.isdigit() or (t[0].isalpha() or t[0] == "_"):
out.append(t)
elif t in prec:
while ops and ops[-1] in prec and prec[ops[-1]] >= prec[t]:
out.append(ops.pop())
ops.append(t)
while ops:
out.append(ops.pop())
stack: List[int] = []
for t in out:
if t in prec:
b = stack.pop(); a = stack.pop()
if t == "+": stack.append(a + b)
elif t == "-": stack.append(a - b)
elif t == "*": stack.append(a * b)
else: stack.append(a // b if a * b >= 0 else -((-a) // b) if a < 0 else a // b)
elif t.isdigit():
stack.append(int(t))
else:
stack.append(resolve(t))
if has_cycle[0]:
return 0
return stack[0]
def resolve(name: str) -> int:
if has_cycle[0]:
return 0
if name in cache:
return cache[name]
if name in visiting:
has_cycle[0] = True
return 0
visiting.add(name)
v = evaluate(defs[name])
visiting.remove(name)
cache[name] = v
return v
results: List[str] = []
for name in order:
v = resolve(name)
if has_cycle[0]:
return ["CYCLE"]
results.append(f"{name}={v}")
return resultsimport java.util.*;
import java.util.regex.*;
class Solution {
private Map<String, String> defs = new HashMap<>();
private Map<String, Integer> cache = new HashMap<>();
private Set<String> visiting = new HashSet<>();
private boolean hasCycle = false;
String[] evaluateExpressionMap(String[] definitions) {
List<String> order = new ArrayList<>();
for (String d : definitions) {
int eq = d.indexOf('=');
String name = d.substring(0, eq).trim();
defs.put(name, d.substring(eq + 1).trim());
order.add(name);
}
List<String> results = new ArrayList<>();
for (String name : order) {
int v = resolve(name);
if (hasCycle) return new String[]{"CYCLE"};
results.add(name + "=" + v);
}
return results.toArray(new String[0]);
}
private int resolve(String name) {
if (hasCycle) return 0;
if (cache.containsKey(name)) return cache.get(name);
if (visiting.contains(name)) { hasCycle = true; return 0; }
visiting.add(name);
int v = evaluate(defs.get(name));
visiting.remove(name);
cache.put(name, v);
return v;
}
private int evaluate(String expr) {
List<String> tokens = new ArrayList<>();
Matcher m = Pattern.compile("\\d+|[A-Za-z_][A-Za-z_0-9]*|[+\\-*/()]").matcher(expr);
while (m.find()) tokens.add(m.group());
Map<String, Integer> prec = Map.of("+", 1, "-", 1, "*", 2, "/", 2);
List<String> out = new ArrayList<>();
Deque<String> ops = new ArrayDeque<>();
for (String t : tokens) {
if (t.matches("\\d+") || Character.isLetter(t.charAt(0)) || t.charAt(0) == '_') out.add(t);
else if (prec.containsKey(t)) {
while (!ops.isEmpty() && prec.containsKey(ops.peek()) && prec.get(ops.peek()) >= prec.get(t)) out.add(ops.pop());
ops.push(t);
}
}
while (!ops.isEmpty()) out.add(ops.pop());
Deque<Integer> stack = new ArrayDeque<>();
for (String t : out) {
if (prec.containsKey(t)) {
int b = stack.pop(), a = stack.pop();
switch (t) {
case "+": stack.push(a + b); break;
case "-": stack.push(a - b); break;
case "*": stack.push(a * b); break;
default: stack.push(a / b);
}
} else if (t.matches("\\d+")) stack.push(Integer.parseInt(t));
else { stack.push(resolve(t)); if (hasCycle) return 0; }
}
return stack.peek();
}
}#include <vector>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <regex>
class Solution {
std::unordered_map<std::string, std::string> defs;
std::unordered_map<std::string, int> cache;
std::unordered_set<std::string> visiting;
bool hasCycle = false;
int evaluate(const std::string& expr) {
std::vector<std::string> tokens;
std::regex re("\\d+|[A-Za-z_][A-Za-z_0-9]*|[+\\-*/()]");
for (auto it = std::sregex_iterator(expr.begin(), expr.end(), re); it != std::sregex_iterator(); ++it)
tokens.push_back(it->str());
std::unordered_map<std::string, int> prec{{"+", 1}, {"-", 1}, {"*", 2}, {"/", 2}};
std::vector<std::string> out;
std::stack<std::string> ops;
for (auto& t : tokens) {
if (isdigit(t[0]) || isalpha(t[0]) || t[0] == '_') out.push_back(t);
else if (prec.count(t)) {
while (!ops.empty() && prec.count(ops.top()) && prec[ops.top()] >= prec[t]) { out.push_back(ops.top()); ops.pop(); }
ops.push(t);
}
}
while (!ops.empty()) { out.push_back(ops.top()); ops.pop(); }
std::stack<int> st;
for (auto& t : out) {
if (prec.count(t)) {
int b = st.top(); st.pop();
int a = st.top(); st.pop();
if (t == "+") st.push(a + b);
else if (t == "-") st.push(a - b);
else if (t == "*") st.push(a * b);
else st.push(a / b);
} else if (isdigit(t[0])) st.push(std::stoi(t));
else { st.push(resolve(t)); if (hasCycle) return 0; }
}
return st.top();
}
int resolve(const std::string& name) {
if (hasCycle) return 0;
auto it = cache.find(name);
if (it != cache.end()) return it->second;
if (visiting.count(name)) { hasCycle = true; return 0; }
visiting.insert(name);
int v = evaluate(defs[name]);
visiting.erase(name);
cache[name] = v;
return v;
}
public:
std::vector<std::string> evaluateExpressionMap(std::vector<std::string>& definitions) {
std::vector<std::string> order;
for (auto& d : definitions) {
auto eq = d.find('=');
std::string name = d.substr(0, eq);
defs[name] = d.substr(eq + 1);
order.push_back(name);
}
std::vector<std::string> results;
for (auto& name : order) {
int v = resolve(name);
if (hasCycle) return {"CYCLE"};
results.push_back(name + "=" + std::to_string(v));
}
return results;
}
};Complete the function below. The function receives the full standard input as a single string and returns the exact standard output lines for a small spreadsheet engine.
Implement a spreadsheet with cell labels such as A1 and B10. The spreadsheet supports setting cells to integers or formulas, retrieving evaluated values, and detecting cycles.
A formula is a +-separated expression containing non-negative integer literals and/or cell labels. Operators other than + are not required.
Supported commands:
SET label value: setlabelto an integer or formula. ReturnOKif the assignment does not create a dependency cycle; otherwise leave the spreadsheet unchanged and returnERROR.GET label: return the evaluated integer value oflabel. ReturnERRORif the cell is unset or cannot be evaluated. Cell dependencies are evaluated lazily or eagerly as you choose, butGETmust always reflect the latest committed cell values. Function Description CompletesolveSpreadsheetFormulaEvaluator. It has one parameter,String input, containing newline-separated commands. Return the stdout payload as an array of lines, without trailing newline characters.
Constraints
Cell labels consist of uppercase letters followed by digits, such as A1 or B10.
Formula expressions only need to support addition with +.
Assignments that introduce a cycle must be rejected.
解锁全部 1 道题的解法
题面你已经看到了 — 解法 + 三语代码 + 复杂度推导 + 边界讨论, Pro 解锁.
- 📚1000+ 道真实北美 OA, Python / Java / C++ 三语题解
- 📊个人 dashboard + 进度可视化 + 14 天活跃图
- 📝题目笔记跨设备同步 + 个人复盘库
- 🔓随时取消下次续费, Stripe Customer Portal 自助管理