Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}

}

}