From bf87a113995ff79ee34866dea233a41b68d0c1ef Mon Sep 17 00:00:00 2001 From: johnChnia Date: Thu, 20 Apr 2017 01:23:21 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=8C=E6=88=90prefix,postfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/stack/expr/InfixExpr.java | 15 +++++ .../basic/stack/expr/InfixExprTest.java | 52 +++++++++++++++++ .../basic/stack/expr/InfixToPostfix.java | 14 +++++ .../coding2017/basic/stack/expr/Operator.java | 41 +++++++++++++ .../basic/stack/expr/PostfixExpr.java | 27 +++++++++ .../basic/stack/expr/PostfixExprTest.java | 41 +++++++++++++ .../basic/stack/expr/PrefixExpr.java | 25 ++++++++ .../basic/stack/expr/PrefixExprTest.java | 45 ++++++++++++++ .../coding2017/basic/stack/expr/Token.java | 50 ++++++++++++++++ .../basic/stack/expr/TokenParser.java | 58 +++++++++++++++++++ .../basic/stack/expr/TokenParserTest.java | 39 +++++++++++++ 11 files changed, 407 insertions(+) create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExprTest.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExprTest.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExpr.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExprTest.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Token.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParser.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParserTest.java diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..ddafe58c46 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java @@ -0,0 +1,15 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + return 0.0f; + } + + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExprTest.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..e47a8841da --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExprTest.java @@ -0,0 +1,52 @@ +package com.johnChnia.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*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); + } + { + InfixExpr expr = new InfixExpr("10-2*3+50"); + Assert.assertEquals(54, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java new file mode 100644 index 0000000000..f42f73282a --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java @@ -0,0 +1,14 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +import java.util.List; + +public class InfixToPostfix { + + public static List convert(String expr) { + + return null; + } + + + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java new file mode 100644 index 0000000000..52ff15fa80 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java @@ -0,0 +1,41 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +import com.johnChnia.coding2017.basic.stack.Stack; + +/** + * Created by john on 2017/4/20. + */ +public class Operator { + + public void handlerToken(String fix, Stack stack, Token token) { + if (token.isNumber()) { + stack.push(Float.parseFloat(token.toString())); + } else if (token.isOperator()) { + float p = stack.pop(); + float q = stack.pop(); + stack.push(perform(fix, token.toString(), p, q)); + } + } + + private float perform(String fix, String operator, float p, float q) { + float result = 0.0f; + if (operator.equals("+")) { + result = p + q; + } else if (operator.equals("-")) { + if (fix.equals("postfix")) { + result = q - p; + } else if (fix.equals("prefix")){ + result = p - q; + } + } else if (operator.equals("*")) { + result = p * q; + } else if (operator.equals("/")) { + if (fix.equals("postfix")) { + result = q / p; + } else if (fix.equals("prefix")){ + result = p / q; + } + } + return result; + } +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java new file mode 100644 index 0000000000..dfecd16ed4 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java @@ -0,0 +1,27 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +import com.johnChnia.coding2017.basic.List; +import com.johnChnia.coding2017.basic.stack.Stack; + +public class PostfixExpr { + String expr = null; + + public PostfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + TokenParser tokenParser = new TokenParser(); + List tokens = tokenParser.parse(this.expr); + Operator operator = new Operator(); + Stack stack = new Stack<>(); + for (int i = 0; i < tokens.size(); i++) { + operator.handlerToken("postfix", stack, tokens.get(i)); + + } + + return stack.pop(); + } + + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExprTest.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExprTest.java new file mode 100644 index 0000000000..312eed28b3 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExprTest.java @@ -0,0 +1,41 @@ +package com.johnChnia.coding2017.basic.stack.expr; + + + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class PostfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + { + PostfixExpr expr = new PostfixExpr("6 5 2 3 + 8 * + 3 + *"); + Assert.assertEquals(288, expr.evaluate(),0.0f); + } + { + //9+(3-1)*3+10/2 + PostfixExpr expr = new PostfixExpr("9 3 1-3*+ 10 2/+"); + Assert.assertEquals(20, expr.evaluate(),0.0f); + } + + { + //10-2*3+50 + PostfixExpr expr = new PostfixExpr("10 2 3 * - 50 +"); + Assert.assertEquals(54, expr.evaluate(),0.0f); + } + } + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExpr.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExpr.java new file mode 100644 index 0000000000..c16f529845 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExpr.java @@ -0,0 +1,25 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +import com.johnChnia.coding2017.basic.List; +import com.johnChnia.coding2017.basic.stack.Stack; + +public class PrefixExpr { + String expr = null; + + public PrefixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + TokenParser tokenParser = new TokenParser(); + List tokens = tokenParser.parse(this.expr); + Operator operator = new Operator(); + Stack stack = new Stack<>(); + for (int i = tokens.size() - 1; i >= 0; i--) { + operator.handlerToken("prefix", stack, tokens.get(i)); + } + return stack.pop(); + } + + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExprTest.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExprTest.java new file mode 100644 index 0000000000..30f67b2710 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PrefixExprTest.java @@ -0,0 +1,45 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class PrefixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + { + // 2*3+4*5 + PrefixExpr expr = new PrefixExpr("+ * 2 3* 4 5"); + Assert.assertEquals(26, expr.evaluate(), 0.001f); + } + { + // 4*2 + 6+9*2/3 -8 + PrefixExpr expr = new PrefixExpr("-++6/*2 9 3 * 4 2 8"); + Assert.assertEquals(12, expr.evaluate(), 0.001f); + } + { + //(3+4)*5-6 + PrefixExpr expr = new PrefixExpr("- * + 3 4 5 6"); + Assert.assertEquals(29, expr.evaluate(), 0.001f); + } + { + //1+((2+3)*4)-5 + PrefixExpr expr = new PrefixExpr("- + 1 * + 2 3 4 5"); + Assert.assertEquals(16, expr.evaluate(), 0.001f); + } + + + } + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Token.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Token.java new file mode 100644 index 0000000000..f87a210587 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Token.java @@ -0,0 +1,50 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class Token { + public static final List OPERATORS = Arrays.asList("+", "-", "*", "/"); + private static final Map priorities = new HashMap<>(); + static { + priorities.put("+", 1); + priorities.put("-", 1); + priorities.put("*", 2); + priorities.put("/", 2); + } + static final int OPERATOR = 1; + static final int NUMBER = 2; + String value; + int type; + public Token(int type, String value){ + this.type = type; + this.value = value; + } + + public boolean isNumber() { + return type == NUMBER; + } + + public boolean isOperator() { + return type == OPERATOR; + } + + public int getIntValue() { + return Integer.valueOf(value).intValue(); + } + public String toString(){ + return value; + } + + public boolean hasHigherPriority(Token t){ + if(!this.isOperator() && !t.isOperator()){ + throw new RuntimeException("numbers can't compare priority"); + } + return priorities.get(this.value) - priorities.get(t.value) > 0; + } + + + +} \ No newline at end of file diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParser.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParser.java new file mode 100644 index 0000000000..b9c8b80444 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParser.java @@ -0,0 +1,58 @@ +package com.johnChnia.coding2017.basic.stack.expr; + + +import com.johnChnia.coding2017.basic.ArrayList; +import com.johnChnia.coding2017.basic.List; + +public class TokenParser { + + + public List parse(String expr) { + List tokens = new ArrayList<>(); + + int i = 0; + + while (i < expr.length()) { + + char c = expr.charAt(i); + + if (isOperator(c)) { + + Token t = new Token(Token.OPERATOR, String.valueOf(c)); + tokens.add(t); + i++; + + } else if (Character.isDigit(c)) { + + int nextOperatorIndex = indexOfNextOperator(i, expr); + String value = expr.substring(i, nextOperatorIndex); + Token t = new Token(Token.NUMBER, value); + tokens.add(t); + i = nextOperatorIndex; + + } else { + System.out.println("char :[" + c + "] is not number or operator,ignore"); + i++; + } + + } + return tokens; + } + + private int indexOfNextOperator(int i, String expr) { + + while (Character.isDigit(expr.charAt(i))) { + i++; + if (i == expr.length()) { + break; + } + } + return i; + + } + + private boolean isOperator(char c) { + String sc = String.valueOf(c); + return Token.OPERATORS.contains(sc); + } +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParserTest.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParserTest.java new file mode 100644 index 0000000000..cdb3b091db --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/TokenParserTest.java @@ -0,0 +1,39 @@ +package com.johnChnia.coding2017.basic.stack.expr; + +import com.johnChnia.coding2017.basic.List; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class TokenParserTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void test() { + + TokenParser parser = new TokenParser(); + List tokens = parser.parse("300*20+12*5-20/4"); + + Assert.assertEquals(300, tokens.get(0).getIntValue()); + Assert.assertEquals("*", tokens.get(1).toString()); + Assert.assertEquals(20, tokens.get(2).getIntValue()); + Assert.assertEquals("+", tokens.get(3).toString()); + Assert.assertEquals(12, tokens.get(4).getIntValue()); + Assert.assertEquals("*", tokens.get(5).toString()); + Assert.assertEquals(5, tokens.get(6).getIntValue()); + Assert.assertEquals("-", tokens.get(7).toString()); + Assert.assertEquals(20, tokens.get(8).getIntValue()); + Assert.assertEquals("/", tokens.get(9).toString()); + Assert.assertEquals(4, tokens.get(10).getIntValue()); + } + +} From 43607d3df44b89abf4617a9e64a595318a84818a Mon Sep 17 00:00:00 2001 From: johnChnia Date: Fri, 21 Apr 2017 00:20:58 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B8=AD=E5=BA=8F?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/stack/expr/InfixExpr.java | 6 ++- .../basic/stack/expr/InfixToPostfix.java | 39 +++++++++++++++---- .../coding2017/basic/stack/expr/Operator.java | 5 ++- .../basic/stack/expr/PostfixExpr.java | 13 ++++++- 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java index ddafe58c46..d3e9afbf9b 100644 --- a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixExpr.java @@ -1,5 +1,8 @@ package com.johnChnia.coding2017.basic.stack.expr; + +import com.johnChnia.coding2017.basic.List; + public class InfixExpr { String expr = null; @@ -8,7 +11,8 @@ public InfixExpr(String expr) { } public float evaluate() { - return 0.0f; + List tokens = InfixToPostfix.convert(this.expr); + return PostfixExpr.evaluate(tokens); } diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java index f42f73282a..e361815f02 100644 --- a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/InfixToPostfix.java @@ -1,14 +1,37 @@ package com.johnChnia.coding2017.basic.stack.expr; -import java.util.List; +import com.johnChnia.coding2017.basic.ArrayList; +import com.johnChnia.coding2017.basic.List; +import com.johnChnia.coding2017.basic.stack.Stack; + + +/*** + * Rule: + */ public class InfixToPostfix { - - public static List convert(String expr) { - - return null; - } - - + + public static List convert(String expr) { + TokenParser tokenParser = new TokenParser(); + List tokens = tokenParser.parse(expr); + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + for (int i = 0; i < tokens.size(); i++) { + Token token = tokens.get(i); + if (token.isNumber()) { + list.add(token); + } else if (token.isOperator()) { + while (!stack.empty() && !token.hasHigherPriority(stack.peek())) { + list.add(stack.pop()); + } + stack.push(token); + + } + } + while (!stack.empty()) { + list.add(stack.pop()); + } + return list; + } } diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java index 52ff15fa80..adc1aac489 100644 --- a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/Operator.java @@ -17,6 +17,7 @@ public void handlerToken(String fix, Stack stack, Token token) { } } + private float perform(String fix, String operator, float p, float q) { float result = 0.0f; if (operator.equals("+")) { @@ -24,7 +25,7 @@ private float perform(String fix, String operator, float p, float q) { } else if (operator.equals("-")) { if (fix.equals("postfix")) { result = q - p; - } else if (fix.equals("prefix")){ + } else if (fix.equals("prefix")) { result = p - q; } } else if (operator.equals("*")) { @@ -32,7 +33,7 @@ private float perform(String fix, String operator, float p, float q) { } else if (operator.equals("/")) { if (fix.equals("postfix")) { result = q / p; - } else if (fix.equals("prefix")){ + } else if (fix.equals("prefix")) { result = p / q; } } diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java index dfecd16ed4..4046c13830 100644 --- a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/expr/PostfixExpr.java @@ -4,7 +4,9 @@ import com.johnChnia.coding2017.basic.stack.Stack; public class PostfixExpr { - String expr = null; + private String expr = null; + static Operator operator = new Operator(); + public PostfixExpr(String expr) { this.expr = expr; @@ -13,7 +15,6 @@ public PostfixExpr(String expr) { public float evaluate() { TokenParser tokenParser = new TokenParser(); List tokens = tokenParser.parse(this.expr); - Operator operator = new Operator(); Stack stack = new Stack<>(); for (int i = 0; i < tokens.size(); i++) { operator.handlerToken("postfix", stack, tokens.get(i)); @@ -23,5 +24,13 @@ public float evaluate() { return stack.pop(); } + public static float evaluate(List tokens) { + Stack stack = new Stack<>(); + for (int i = 0; i < tokens.size(); i++) { + operator.handlerToken("postfix", stack, tokens.get(i)); + } + return stack.pop(); + } + }