Skip to content

Commit

Permalink
Merge pull request onlyliuxin#76 from miniyk2012/master
Browse files Browse the repository at this point in the history
中缀表达式求值V1
  • Loading branch information
Rong Huang authored Apr 17, 2017
2 parents 5e295e3 + 4fd8d2a commit eb7b3fb
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 0 deletions.
1 change: 1 addition & 0 deletions group02/812350401/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ src/main/java/train/
!src/main/resources/**/*.class
!src/main/resources/**/*.xml
src/main/resources/**/*.png
src/main/java/assignments
7 changes: 7 additions & 0 deletions group02/812350401/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.reactivex.rxjava2/rxjava -->
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.0.8</version>
</dependency>

</dependencies>


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package com.github.miniyk2012.coding2017.basic.stack.expr;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class InfixExpr {
private String expr = null;
enum Operator {
PLUS("+", 1), SUB("-", 1), MUL("*", 2), DIV("/", 2); // 优先级越大,说明应该先算
private String value;
private int priority;
Operator(String value, int prioriy) {
this.value = value;
this.priority = prioriy;
}
public static Operator parseOperator(String value) {
for (Operator c : Operator.values()) {
if (c.value.equals(value)) {
return c;
}
}
throw new RuntimeException("运算符不存在");
}
}

public InfixExpr(String expr) {
this.expr = expr;
}
private static Token<Float> evaluate(Token<Operator> operator, Token<Float> number1, Token<Float> number2) {
float ret;
switch (operator.value) {
case PLUS:
ret = number1.getValue() + number2.getValue();
break;
case SUB:
ret = number1.getValue() - number2.getValue();
break;
case MUL:
ret = number1.getValue() * number2.getValue();
break;
case DIV:
ret = number1.getValue() / number2.getValue();
break;
default:
throw new RuntimeException("运算符不存在");
}
return new Token(ret, true);
}


public float evaluate() {
List<Token> tokens= Token.parse(expr);
Stack<Token<Float>> numberStack = new Stack<>();
Stack<Token<Operator>> operatorStack = new Stack<>();
for (Token t : tokens) {
if (t.isNumber()) {
numberStack.push(t);
} else {
if (operatorStack.isEmpty()) {
operatorStack.push(t);
} else {
Token<Operator> preT = operatorStack.peek();
if ((preT.value).priority >= ((Operator)t.value).priority) {
Token number2 = numberStack.pop();
Token number1 = numberStack.pop();
operatorStack.pop();
numberStack.push(evaluate(preT, number1, number2));
}
operatorStack.push(t);

}
}
}
while (!operatorStack.isEmpty()) {
Token number2 = numberStack.pop();
Token number1 = numberStack.pop();
Token operator = operatorStack.pop();
numberStack.push(evaluate(operator, number1, number2));
}
return numberStack.pop().getValue();
}


private static class Token<T> {
private boolean number; // 是数字/操作符
private T value;
public boolean isNumber() {
return number;
}
public T getValue() {
return value;
}

public Token(T value, boolean number) {
this.value = value;
this.number = number;
}
public static List<Token> parse(String expr) {
int i = 0;
int size = expr.length();
String current;
List<Token> tokens = new LinkedList<>();
String value = "";
while (i < size) {
current = expr.substring(i,i+1);
if (isOperator(current)) {
tokens.add(new Token(Float.parseFloat(value), true));
value = "";
tokens.add(new Token(Operator.parseOperator(current), false));
} else {
value += current;
}
i++;
}
tokens.add(new Token(Float.parseFloat(value), true));
return tokens;
}

private static boolean isOperator(String value) {
for (Operator c : Operator.values()) {
if (c.value.equals(value)) {
return true;
}
}
return false;
}
}

public static void main(String[] args) {


}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.github.miniyk2012.coding2017.basic.stack.expr;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;


public class InfixExprTest {

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public void testEvaluate() {
//InfixExpr expr = new InfixExpr("300*20+12*5-20/4");
{
InfixExpr expr = new InfixExpr("2+3");
Assert.assertEquals(5.0, expr.evaluate(), 0.001f);
}
{
InfixExpr expr = new InfixExpr("2+3*4+5");
Assert.assertEquals(19.0, expr.evaluate(), 0.001f);
}
{
InfixExpr expr = new InfixExpr("3*20+12*5-40/2");
Assert.assertEquals(100.0, expr.evaluate(), 0.001f);
}

{
InfixExpr expr = new InfixExpr("3*20/2");
Assert.assertEquals(30, expr.evaluate(), 0.001f);
}

{
InfixExpr expr = new InfixExpr("20/2*3");
Assert.assertEquals(30, expr.evaluate(), 0.001f);
}

{
InfixExpr expr = new InfixExpr("10-30+50");
Assert.assertEquals(30, expr.evaluate(), 0.001f);
}

}

}

0 comments on commit eb7b3fb

Please sign in to comment.