static String toHex(int n) {
Stack<String> stack = new Stack<>();
int remainder;
for (;n > 0;) {
remainder = n % 16; n = n / 16;
stack.push(remainder < 10 ? String.format("%d", remainder) : String.format("%c", 55+remainder));
}
String output = "";
for (;!stack.empty();) output+=stack.pop();
return output;
}
第二题和第三题的compile适应于多数情况。
static SuffixExpression compile(String exp) {
// TODO: Stack<String> outs = new Stack<>();
Stack<String> signs = new Stack<>();
Map<String, Integer> level = new HashMap<>(); // 主要是设置好运算符号的优先级
level.put("+", 1); level.put("-", 1);
level.put("*", 2); level.put("/", 2); level.put("%", 2); level.put("//", 2);
level.put("^", 3); // 这里加入了乘方。
level.put("(", 4); level.put(")", 4);
String part = "";
for (char c : exp.toCharArray()) {
if (c == ' ')continue;
String s = String.valueOf(c);
if (level.containsKey(s)) { //如果是符号,就要判断优先级,进行入栈或者出栈的操作,还要判断好左右括号。
if (part.length() > 0) outs.push(part); part = "";
Integer sig = level.get(s);
while ((!signs.empty()) && sig <= level.get(signs.peek())&&level.get(signs.peek())!=4){ outs.push(signs.pop()); }//两个栈,可以做出队列的效果。
if (s.equals(")")) {
while ((!signs.empty())&&(!signs.peek().equals("("))){ outs.push(signs.pop()); } signs.pop();
} else { signs.push(s); }
}else{part += s;}
}
if (part.length() > 0) outs.push(part);
for (;!signs.empty();){ // 把栈中的剩余符号压出来
String p = signs.pop();
outs.push(p);
}
return new SuffixExpression(outs);
}
}
第二题和第三题的类 和 两个实现方法,应该还有很大优化空间
class SuffixExpression {
public Stack<String> exp;
private Exception NullPointerException;
public SuffixExpression(Stack<String> exp){
this.exp = exp;
}
int execute() {
// TODO:
Stack<Integer> result = new Stack<>();
for (String s: this.exp){
boolean isNumber = true; // 假设是数字
boolean isSign = true; // 假设是运算符号
for (int i=0; i< s.length();i++){ // 整个循环判断判断是否是数字,其实可以用正则,但是没学到那呢,所以先不写
if (!Character.isDigit(s.charAt(i)))
isNumber= false;break;
}
if (isNumber) { // 这里写的很难受,Python有else语法,但是java没有。
result.push(Integer.valueOf(s));continue;
}
if (!(s.length()==1&&"+-*/^".contains(s))) isSign=false;
if (isSign){ // 确定是运算符号的话,一定是有两个操作数,也就是栈顶的两个。
Integer b = result.pop();
Integer a = result.pop();
switch (s.toCharArray()[0]){
case '+': a += b;break;
case '-': a -= b;break;
case '*': a *= b;break;
case '/': a /= b;break;
case '^': a = (Integer) (int)Math.pow(a, b);break; // 这里是加入的乘方的操作
}
result.push(a);
}
}
return result.pop();
}
int execute(Map<String, Integer> env) throws Exception {
// TODO:
Stack<Integer> result = new Stack<>();
for (String s: this.exp){
boolean isNumber = true;
boolean isSign = true;
for (int i=0; i< s.length();i++){
if (!Character.isDigit(s.charAt(i)))
isNumber= false;break;
}
if (isNumber) {
result.push(Integer.valueOf(s));continue;
}
if (!(s.length()==1&&"+-*/^".contains(s))) isSign=false;
if (isSign){
Integer b = result.pop();
Integer a = result.pop();
switch (s.toCharArray()[0]){
case '+': a += b;break;
case '-': a -= b;break;
case '*': a *= b;break;
case '/': a /= b;break;
case '^': a = (Integer) (int)Math.pow(a, b);break;
}
result.push(a);
continue;
}
Integer v = env.get(s);
if (v == null) {
throw NullPointerException; // 这里如果得到不到s对应的数字会报错
}
result.push(v);
}
return result.pop();
}
}
_崔先生_
第一题几行就能出来。
第二题和第三题的compile适应于多数情况。
第二题和第三题的类 和 两个实现方法,应该还有很大优化空间