从映射中递归查找字符串的值
recursively finding value of a String from a map
我有一个包含 Key 和 Value 的 hashmap <String, String>
。
即地图值:
mapValue.put("A","B-7");
mapValue.put("B","START+18");
mapValue.put("C","A+25");
现在我想计算 'C'
的表达式。所以对于 C
,表达式将是
替换为 (((START+18)-7)+25)
.
所以如果有任何方法,我将传递字符串 C
,它应该是 return 字符串
"(((START+18)-7)+25)"
而且我想按优先级来评估它。
谢谢
如评论中所述,我不推荐递归 - 如果递归太深,它可能会导致 Whosebug 异常。
另外我建议不要使用字符串方程。字符串解析速度很慢,可能会导致意外结果(如@rtruszk 所述 "START" 包含变量 "A")。
我创建了一个示例作为我的推荐:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class X {
static interface Expression {
}
static class Combination implements Expression {
Expression[] values;
public Combination(Expression... values) {
this.values = values;
}
@Override
public String toString() {
return "?";
}
}
static class Reference implements Expression {
private String reference;
public Reference(String reference) {
this.reference = reference;
}
@Override
public String toString() {
return reference;
}
}
static class Number implements Expression {
private int value;
public Number(int value) {
this.value = value;
}
@Override
public String toString() {
return ""+value;
}
}
public static void main(String[] args) {
Map<String, Expression> mapValue = new HashMap<>();
mapValue.put("START", new Number(42));
String x = "C";
mapValue.put("A", new Combination( new Reference("B"), new Number(-7)));
mapValue.put("B", new Combination(new Reference("START"), new Number(+18)));
mapValue.put("C", new Combination( new Reference("A"), new Number(+25)));
int result = 0;
ArrayList<Expression> parts = new ArrayList<>();
parts.add(mapValue.get(x));
while (!parts.isEmpty()) {
debuggingOutput(x, result, parts);
Expression expression = parts.remove(0);
if (expression instanceof Combination)
parts.addAll(Arrays.asList(((Combination) expression).values));
else if (expression instanceof Reference)
parts.add(mapValue.get(((Reference) expression).reference));
else if (expression instanceof Number)
result += ((Number) expression).value;
}
System.out.println(result);
}
private static void debuggingOutput(String x, int result, ArrayList<Expression> parts) {
System.out.print(x);
System.out.print(" = ");
System.out.print(result);
for (Expression part : parts) {
System.out.print(" + ");
System.out.print(part);
}
System.out.println();
}
}
这种函数的一般逻辑(假设,你知道可能的操作和语法是严格的)可能如下:
public String eval(HashMap<String, String> mapValue, String variable) {
//get expression to be evaluated
String tmp = mapValue.get(variable);
// For each knwon operation
for (String op : OPERATIONS) {
// split expression in operators in Array
String[] vars = tmp.split("\" + op);
// for each Element of splitted expr. Array
for (int i = 0; i < vars.length; i++) {
//Check if Element is a valid key in HashMap
if (mapValue.containsKey(vars[i])) {
//if it is replace element with result of iteration
vars[i] = eval(mapValue, vars[i]); // DO ITERATION
}
//if Element is not a valid key in has do nothing
}
//Join splitted string with proper operator
tmp = join(vars, op);
}
//return in parenthesis
return "(" + tmp + ")";
}
'eval(mapValue,"C")' 的结果将是:
(((START+18)-7)+25)
一些short join函数可能实现如下:
public String join(String[] arr, String d) {
String result = arr[0];
int i = 1;
while (i < arr.length) {
result += d + arr[i];
i++;
}
return result;
}
上面提供的所有代码更多的是为了说明逻辑,因为应该使用一些异常处理、更好的字符串操作等。
希望对您有所帮助
干杯!
我有一个包含 Key 和 Value 的 hashmap <String, String>
。
即地图值:
mapValue.put("A","B-7");
mapValue.put("B","START+18");
mapValue.put("C","A+25");
现在我想计算 'C'
的表达式。所以对于 C
,表达式将是
替换为 (((START+18)-7)+25)
.
所以如果有任何方法,我将传递字符串 C
,它应该是 return 字符串
"(((START+18)-7)+25)"
而且我想按优先级来评估它。
谢谢
如评论中所述,我不推荐递归 - 如果递归太深,它可能会导致 Whosebug 异常。
另外我建议不要使用字符串方程。字符串解析速度很慢,可能会导致意外结果(如@rtruszk 所述 "START" 包含变量 "A")。
我创建了一个示例作为我的推荐:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class X {
static interface Expression {
}
static class Combination implements Expression {
Expression[] values;
public Combination(Expression... values) {
this.values = values;
}
@Override
public String toString() {
return "?";
}
}
static class Reference implements Expression {
private String reference;
public Reference(String reference) {
this.reference = reference;
}
@Override
public String toString() {
return reference;
}
}
static class Number implements Expression {
private int value;
public Number(int value) {
this.value = value;
}
@Override
public String toString() {
return ""+value;
}
}
public static void main(String[] args) {
Map<String, Expression> mapValue = new HashMap<>();
mapValue.put("START", new Number(42));
String x = "C";
mapValue.put("A", new Combination( new Reference("B"), new Number(-7)));
mapValue.put("B", new Combination(new Reference("START"), new Number(+18)));
mapValue.put("C", new Combination( new Reference("A"), new Number(+25)));
int result = 0;
ArrayList<Expression> parts = new ArrayList<>();
parts.add(mapValue.get(x));
while (!parts.isEmpty()) {
debuggingOutput(x, result, parts);
Expression expression = parts.remove(0);
if (expression instanceof Combination)
parts.addAll(Arrays.asList(((Combination) expression).values));
else if (expression instanceof Reference)
parts.add(mapValue.get(((Reference) expression).reference));
else if (expression instanceof Number)
result += ((Number) expression).value;
}
System.out.println(result);
}
private static void debuggingOutput(String x, int result, ArrayList<Expression> parts) {
System.out.print(x);
System.out.print(" = ");
System.out.print(result);
for (Expression part : parts) {
System.out.print(" + ");
System.out.print(part);
}
System.out.println();
}
}
这种函数的一般逻辑(假设,你知道可能的操作和语法是严格的)可能如下:
public String eval(HashMap<String, String> mapValue, String variable) {
//get expression to be evaluated
String tmp = mapValue.get(variable);
// For each knwon operation
for (String op : OPERATIONS) {
// split expression in operators in Array
String[] vars = tmp.split("\" + op);
// for each Element of splitted expr. Array
for (int i = 0; i < vars.length; i++) {
//Check if Element is a valid key in HashMap
if (mapValue.containsKey(vars[i])) {
//if it is replace element with result of iteration
vars[i] = eval(mapValue, vars[i]); // DO ITERATION
}
//if Element is not a valid key in has do nothing
}
//Join splitted string with proper operator
tmp = join(vars, op);
}
//return in parenthesis
return "(" + tmp + ")";
}
'eval(mapValue,"C")' 的结果将是:
(((START+18)-7)+25)
一些short join函数可能实现如下:
public String join(String[] arr, String d) {
String result = arr[0];
int i = 1;
while (i < arr.length) {
result += d + arr[i];
i++;
}
return result;
}
上面提供的所有代码更多的是为了说明逻辑,因为应该使用一些异常处理、更好的字符串操作等。
希望对您有所帮助
干杯!