diff --git a/group09/610673813/src/coding/week04/lru/LRUPageFrame.java b/group09/610673813/src/coding/week04/lru/LRUPageFrame.java new file mode 100644 index 0000000000..f468be7063 --- /dev/null +++ b/group09/610673813/src/coding/week04/lru/LRUPageFrame.java @@ -0,0 +1,116 @@ +package coding.week04.lru; + +public class LRUPageFrame { + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(Node prev, Node next, int pageNum) { + this.prev = prev; + this.next = next; + this.pageNum = pageNum; + } + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + private int size; // 链表长度 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + int index = find(pageNum); + if (size != 0) { + if(index >= 0){ + remove(index); + }else if(size == capacity){ + remove(size - 1); + } + } + addToHead(pageNum); + } + + public void remove(int index) { + if (index == 0) { + if(size == 1){ + first = last = null; + }else{ + first = first.next; + first.prev = null; + } + } else if (index == (size - 1)) { + if(size == 1){ + first = last = null; + }else{ + last = last.prev; + last.next = null; + } + } else { + Node node = first; + for (int i = 1; i < index; i++) { + node = node.next; + } + + Node nxt = node.next; + + node.next = nxt.next; + (nxt.next).prev = node; + nxt = null; + } + size--; + } + + public int find(int pageNum) { + int index = 0; + Node cur = first; + while (cur != null) { + if (pageNum == cur.pageNum) { + return index; + } + cur = cur.next; + index++; + } + return -1; + } + + public void addToHead(int pageNum) { + // 链表为空 + if (first == null) { + Node node = new Node(null, null, pageNum); + first = node; + last = node; + } else { + Node node = new Node(null,first,pageNum); + first.prev = node; + first = node; + } + size ++; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first; + while (node != null) { + buffer.append(node.pageNum); + + node = node.next; + if (node != null) { + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group09/610673813/src/coding/week04/minijvm/loader/ClassFileLoader.java b/group09/610673813/src/coding/week04/minijvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..6ed2d88330 --- /dev/null +++ b/group09/610673813/src/coding/week04/minijvm/loader/ClassFileLoader.java @@ -0,0 +1,67 @@ +package coding.week04.minijvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws IOException { + if(className == null){ + return null; + } + + boolean isFileExist = false; + File file = null; + String classPath = className.replace(".", "\\"); + for(int i = 0 ; i < clzPaths.size(); i++){ + String basePath = clzPaths.get(i); + file = new File(basePath + File.separator + classPath + ".class"); + + if(file.exists()){ + isFileExist = true; + break; + } + } + + //找不到类 + if(!isFileExist){ + throw new FileNotFoundException(); + } + + //读取字节码文件到数组 + FileInputStream in = new FileInputStream(file); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte [] rs = new byte[1024]; + int len = 0; + while((len = in.read(rs)) != -1){ + bos.write(rs, 0, len); + } + bos.close(); + in.close(); + System.out.println("readBinaryCode:" + " file size = " + file.length()); + return bos.toByteArray(); + } + + public void addClassPath(String path) { + if(! clzPaths.contains(path)){ + clzPaths.add(path); + } + } + + public String getClassPath() { + StringBuffer buffer = new StringBuffer(); + for(int i = 0;i < clzPaths.size();i++){ + buffer.append(clzPaths.get(i)); + if(i != clzPaths.size() - 1){ + buffer.append(";"); + } + } + return buffer.toString(); + } +} diff --git a/group09/610673813/src/coding/week04/test/ClassFileloaderTest.java b/group09/610673813/src/coding/week04/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..0be59674ba --- /dev/null +++ b/group09/610673813/src/coding/week04/test/ClassFileloaderTest.java @@ -0,0 +1,78 @@ +package coding.week04.test; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week04.minijvm.loader.ClassFileLoader; + + +public class ClassFileloaderTest { + static String path1 = "D:\\Git_2017\\coding2017\\group01\\1298552064\\bin"; + static String path2 = "C:\\temp"; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1 + ";" + path2, clzPath); + } + + @Test + public void testClassFileLength() throws IOException { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "week04.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1032, byteCodes.length); + + } + + @Test + public void testMagicNumber() throws IOException { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "week04.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[] { byteCodes[0], byteCodes[1], byteCodes[2], + byteCodes[3] }; + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + private String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group09/610673813/src/coding/week04/test/EmployeeV1.java b/group09/610673813/src/coding/week04/test/EmployeeV1.java new file mode 100644 index 0000000000..be0a4765db --- /dev/null +++ b/group09/610673813/src/coding/week04/test/EmployeeV1.java @@ -0,0 +1,30 @@ +package coding.week04.test; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} diff --git a/group09/610673813/src/coding/week04/test/LRUPageFrameTest.java b/group09/610673813/src/coding/week04/test/LRUPageFrameTest.java new file mode 100644 index 0000000000..d394628ce1 --- /dev/null +++ b/group09/610673813/src/coding/week04/test/LRUPageFrameTest.java @@ -0,0 +1,30 @@ +package coding.week04.test; + +import org.junit.Assert; +import org.junit.Test; + +import coding.week04.lru.LRUPageFrame; + + +public class LRUPageFrameTest { + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } +} diff --git a/group09/610673813/src/coding/week05/basic/StackUtil.java b/group09/610673813/src/coding/week05/basic/StackUtil.java new file mode 100644 index 0000000000..d958c88f40 --- /dev/null +++ b/group09/610673813/src/coding/week05/basic/StackUtil.java @@ -0,0 +1,110 @@ +package coding.week05.basic; + +import java.util.Stack; + +public class StackUtil { + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + Stack reverseStack = new Stack<>(); + Stack sequenceStack = new Stack<>(); + while(!s.isEmpty()){ + reverseStack.push(s.pop()); + } + + while(!reverseStack.isEmpty()){ + sequenceStack.push(reverseStack.pop()); + } + + while(!sequenceStack.isEmpty()){ + s.push(sequenceStack.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void remove(Stack s,Object o) { + Stack tmpStack = new Stack<>(); + while(!s.isEmpty()){ + if(s.peek().equals(o)){ + s.pop(); + }else{ + tmpStack.push(s.pop()); + } + } + + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Object[] getTop(Stack s,int len) { + if(len < 0 ||len > s.size()){ + throw new IllegalArgumentException("len is invalid argument."); + } + + Object[] objects = new Object[len]; + Stack tmpStack = new Stack<>(); + int index = 0; + while(!s.isEmpty() && index < len){ + Object o = s.pop(); + tmpStack.push(o); + objects[index++] = o; + } + + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + return objects; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的,该方法返回false; + * + * @param s + * @return + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static boolean isValidPairs(String s){ + String symStr = ""; + Stack symStack = new Stack<>(); + for(int i = 0; i < s.length(); i++){ + if(!Character.isLetter(s.charAt(i))){ + symStack.push(s.charAt(i)); + symStr += s.charAt(i); + } + } + + for(int i=0; i< symStr.length();i++){ + char s1 = symStr.charAt(i); + char s2 = (char) symStack.pop(); + if(s1 == '(' && s2 != ')'){ + return false; + } + if(s1 == '[' && s2 != ']'){ + return false; + } + if(s1 == '{' && s2 != '}'){ + return false; + } + } + + return true; + } +} diff --git a/group09/610673813/src/coding/week05/test/StackUtilTest.java b/group09/610673813/src/coding/week05/test/StackUtilTest.java new file mode 100644 index 0000000000..2706592466 --- /dev/null +++ b/group09/610673813/src/coding/week05/test/StackUtilTest.java @@ -0,0 +1,69 @@ +package coding.week05.test; + +import java.util.Stack; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week05.basic.StackUtil; + + +public class StackUtilTest { + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + + @Test + public void testReverse() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + System.out.println(s.toString()); + } + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} diff --git a/group09/610673813/src/coding/week06/basic/InfixExpr.java b/group09/610673813/src/coding/week06/basic/InfixExpr.java new file mode 100644 index 0000000000..d7f54636fc --- /dev/null +++ b/group09/610673813/src/coding/week06/basic/InfixExpr.java @@ -0,0 +1,102 @@ +package coding.week06.basic; + +import java.util.List; +import java.util.Stack; + +public class InfixExpr { + private String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + /** + * 计算 + * @param operator 运算符 + * @param i1 操作数1 + * @param i2 操作数2 + * @return + */ + private int cal(char operator, int i1, int i2){ + int result = 0; + switch(operator){ + case '+' : result = i1 + i2 ; break; + case '-' : result = i1 - i2 ; break; + case '*' : result = i1 * i2 ; break; + case '/' : + if(i1 == 0){ + throw new ArithmeticException("除数不能为0"); + } + result = i1 / i2 ; break; + } + return result; + } + + public float evaluate() { + TokenParser tokenParser = new TokenParser(); + List tokens = tokenParser.parse(expr); + Stack operatorStack = new Stack<>(); + Stack operandStack = new Stack<>(); + for(Token token : tokens){ + if(token.isNumber()){ + operandStack.push(token.getIntValue()); + continue; + } + + if(token.isOperator()){ + if(operatorStack.isEmpty()){ + operatorStack.push(token); + continue; + } + + Token pre = operatorStack.peek(); + boolean hasHigherPriority = token.hasHigherPriority(pre); + if(hasHigherPriority){ + operatorStack.push(token); + }else{ + int n2 = operandStack.pop(); + int n1 = operandStack.pop(); + String operator = operatorStack.pop().value; + operatorStack.push(token); + operandStack.push(cal(operator.charAt(0), n1, n2)); + } + } + } + + while(!operatorStack.isEmpty()){ + if(operatorStack.size() == 1){ + int n2 = operandStack.pop(); + int n1 = operandStack.pop(); + String operator = operatorStack.pop().value; + operandStack.push(cal(operator.charAt(0), n1, n2)); + break; + } + + Token cur = operatorStack.pop(); + Token pre = operatorStack.pop(); + if(cur.hasHigherPriority(pre)){ + int n2 = operandStack.pop(); + int n1 = operandStack.pop(); + operandStack.push(cal(cur.value.charAt(0), n1, n2)); + + operatorStack.push(pre); + }else{ + int n3 = operandStack.pop(); + int n2 = operandStack.pop(); + int n1 = operandStack.pop(); + operandStack.push(cal(pre.value.charAt(0), n1, n2)); + operandStack.push(n3); + + operatorStack.push(cur); + } + + } + return (float)operandStack.pop(); + } + + public static void main(String[] args) { + InfixExpr expr = new InfixExpr("10-2*3+50"); + System.out.println(expr.evaluate()); + } + +} diff --git a/group09/610673813/src/coding/week06/basic/Token.java b/group09/610673813/src/coding/week06/basic/Token.java new file mode 100644 index 0000000000..c077ab6f36 --- /dev/null +++ b/group09/610673813/src/coding/week06/basic/Token.java @@ -0,0 +1,53 @@ +package coding.week06.basic; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Token { + static final int OPERATOR = 1; + static final int NUMBER = 2; + String value; + int type; + 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); + } + + + public Token(int type, String value){ + this.type = type; + this.value = value; + } + + public boolean isOperator(){ + return type == OPERATOR; + } + + public boolean isNumber(){ + return type == NUMBER; + } + + public int getIntValue(){ + return Integer.parseInt(value); + } + + @Override + 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; + + } + +} diff --git a/group09/610673813/src/coding/week06/basic/TokenParser.java b/group09/610673813/src/coding/week06/basic/TokenParser.java new file mode 100644 index 0000000000..9edfd66f3a --- /dev/null +++ b/group09/610673813/src/coding/week06/basic/TokenParser.java @@ -0,0 +1,44 @@ +package coding.week06.basic; + +import java.util.ArrayList; +import java.util.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 token = new Token(Token.OPERATOR, String.valueOf(c)); + tokens.add(token); + i++; + }else if(Character.isDigit(c)){ + int nextOperatorIndex = indexOfNextOperator(i, expr); + String value = expr.substring(i, nextOperatorIndex); + Token token = new Token(Token.NUMBER, value); + tokens.add(token); + i = nextOperatorIndex; + }else{ + System.out.println("char :[" + c + "] is not number or operator,ignore"); + i++; + } + } + return tokens; + } + + public int indexOfNextOperator(int i,String expr){ + while(Character.isDigit(expr.charAt(i))){ + i++; + if(i == expr.length()){ + break; + } + } + return i; + } + + public boolean isOperator(char c){ + String s = String.valueOf(c); + return Token.OPERATORS.contains(s); + } +} diff --git a/group09/610673813/src/coding/week06/test/InfixExprTest.java b/group09/610673813/src/coding/week06/test/InfixExprTest.java new file mode 100644 index 0000000000..427f4300c5 --- /dev/null +++ b/group09/610673813/src/coding/week06/test/InfixExprTest.java @@ -0,0 +1,53 @@ +package coding.week06.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week06.basic.InfixExpr; + +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/group09/610673813/src/coding/week06/test/TokenParserTest.java b/group09/610673813/src/coding/week06/test/TokenParserTest.java new file mode 100644 index 0000000000..9683dc3504 --- /dev/null +++ b/group09/610673813/src/coding/week06/test/TokenParserTest.java @@ -0,0 +1,40 @@ +package coding.week06.test; + +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week06.basic.Token; +import coding.week06.basic.TokenParser; + +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()); + } +} diff --git a/group09/610673813/src/coding/week07/basic/InfixToPostfix.java b/group09/610673813/src/coding/week07/basic/InfixToPostfix.java new file mode 100644 index 0000000000..8fe95f5c04 --- /dev/null +++ b/group09/610673813/src/coding/week07/basic/InfixToPostfix.java @@ -0,0 +1,45 @@ +package coding.week07.basic; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +public class InfixToPostfix { + public static List convert(String expr) { + TokenParser tokenParser = new TokenParser(); + List tokens = tokenParser.parse(expr); + List rsTokens = new ArrayList<>(); + Stack operatorStack = new Stack<>(); + for(int i=0 ; i < tokens.size(); i++){ + Token token = tokens.get(i); + if(token.isNumber()){ + rsTokens.add(token); + continue; + } + + if(token.isOperator()){ + if(operatorStack.isEmpty()){ + operatorStack.push(token); + continue; + } + + Token curStack = operatorStack.peek(); + if(token.hasHigherPriority(curStack)){ + operatorStack.push(token); + }else{ + while(!operatorStack.isEmpty() && (curStack = operatorStack.peek()).hasHigherPriority(token)){ + rsTokens.add(curStack); + operatorStack.pop(); + } + operatorStack.push(token); + } + + } + } + + while(!operatorStack.isEmpty()){ + rsTokens.add(operatorStack.pop()); + } + return rsTokens; + } +} diff --git a/group09/610673813/src/coding/week07/basic/PostfixExpr.java b/group09/610673813/src/coding/week07/basic/PostfixExpr.java new file mode 100644 index 0000000000..de050f7ff0 --- /dev/null +++ b/group09/610673813/src/coding/week07/basic/PostfixExpr.java @@ -0,0 +1,51 @@ +package coding.week07.basic; + +import java.util.List; +import java.util.Stack; + +public class PostfixExpr { + String expr = null; + + public PostfixExpr(String expr) { + this.expr = expr; + } + + /** + * 计算 + * @param operator 运算符 + * @param i1 操作数1 + * @param i2 操作数2 + * @return + */ + private int cal(char operator, int i1, int i2){ + int result = 0; + switch(operator){ + case '+' : result = i1 + i2 ; break; + case '-' : result = i1 - i2 ; break; + case '*' : result = i1 * i2 ; break; + case '/' : + if(i1 == 0){ + throw new ArithmeticException("除数不能为0"); + } + result = i1 / i2 ; break; + } + return result; + } + + public float evaluate() { + TokenParser tokenParser = new TokenParser(); + List tokens = tokenParser.parse(expr); + Stack numStack = new Stack<>(); + for(int i = 0; i < tokens.size(); i++){ + Token token = tokens.get(i); + if(token.isNumber()){ + numStack.push(token.getIntValue()); + }else if(token.isOperator()){ + int n2 = numStack.pop(); + int n1 = numStack.pop(); + numStack.push(cal(token.value.charAt(0),n1,n2)); + } + } + return (float)numStack.pop() ; + } +} diff --git a/group09/610673813/src/coding/week07/basic/PrefixExpr.java b/group09/610673813/src/coding/week07/basic/PrefixExpr.java new file mode 100644 index 0000000000..104bf1586e --- /dev/null +++ b/group09/610673813/src/coding/week07/basic/PrefixExpr.java @@ -0,0 +1,51 @@ +package coding.week07.basic; + +import java.util.List; +import java.util.Stack; + +public class PrefixExpr { + private String expr = null; + + public PrefixExpr(String expr) { + this.expr = expr; + } + + /** + * 计算 + * @param operator 运算符 + * @param i1 操作数1 + * @param i2 操作数2 + * @return + */ + private int cal(char operator, int i1, int i2){ + int result = 0; + switch(operator){ + case '+' : result = i1 + i2 ; break; + case '-' : result = i1 - i2 ; break; + case '*' : result = i1 * i2 ; break; + case '/' : + if(i1 == 0){ + throw new ArithmeticException("除数不能为0"); + } + result = i1 / i2 ; break; + } + return result; + } + + public float evaluate() { + TokenParser tokenParser = new TokenParser(); + List tokens = tokenParser.parse(expr); + Stack numStack = new Stack<>(); + for(int i = tokens.size() - 1; i >= 0;i--){ + Token token = tokens.get(i); + if(token.isNumber()){ + numStack.push(token.getIntValue()); + }else if(token.isOperator()){ + int n1 = numStack.pop(); + int n2 = numStack.pop(); + numStack.push(cal(token.value.charAt(0), n1, n2)); + } + } + return (float)numStack.pop() ; + } +} diff --git a/group09/610673813/src/coding/week07/basic/Token.java b/group09/610673813/src/coding/week07/basic/Token.java new file mode 100644 index 0000000000..1e0008319a --- /dev/null +++ b/group09/610673813/src/coding/week07/basic/Token.java @@ -0,0 +1,52 @@ +package coding.week07.basic; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Token { + static final int OPERATOR = 1; + static final int NUMBER = 2; + String value; + int type; + 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); + } + + public Token(int type, String value) { + this.type = type; + this.value = value; + } + + public boolean isOperator() { + return type == OPERATOR; + } + + public boolean isNumber() { + return type == NUMBER; + } + + public int getIntValue() { + return Integer.parseInt(value); + } + + @Override + 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; + + } + +} diff --git a/group09/610673813/src/coding/week07/basic/TokenParser.java b/group09/610673813/src/coding/week07/basic/TokenParser.java new file mode 100644 index 0000000000..bf6bcfe8ea --- /dev/null +++ b/group09/610673813/src/coding/week07/basic/TokenParser.java @@ -0,0 +1,44 @@ +package coding.week07.basic; + +import java.util.ArrayList; +import java.util.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 token = new Token(Token.OPERATOR, String.valueOf(c)); + tokens.add(token); + i++; + }else if(Character.isDigit(c)){ + int nextOperatorIndex = indexOfNextOperator(i, expr); + String value = expr.substring(i, nextOperatorIndex); + Token token = new Token(Token.NUMBER, value); + tokens.add(token); + i = nextOperatorIndex; + }else{ + System.out.println("char :[" + c + "] is not number or operator,ignore"); + i++; + } + } + return tokens; + } + + public int indexOfNextOperator(int i,String expr){ + while(Character.isDigit(expr.charAt(i))){ + i++; + if(i == expr.length()){ + break; + } + } + return i; + } + + public boolean isOperator(char c){ + String s = String.valueOf(c); + return Token.OPERATORS.contains(s); + } +} diff --git a/group09/610673813/src/coding/week07/test/InfixToPostfixTest.java b/group09/610673813/src/coding/week07/test/InfixToPostfixTest.java new file mode 100644 index 0000000000..30eac99109 --- /dev/null +++ b/group09/610673813/src/coding/week07/test/InfixToPostfixTest.java @@ -0,0 +1,35 @@ +package coding.week07.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week07.basic.InfixToPostfix; + +public class InfixToPostfixTest { + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testconvert() { + + Assert.assertEquals("[2, 3, 4, *, +, 5, +]", InfixToPostfix.convert("2+3*4+5").toString()); + + Assert.assertEquals("[3, 20, *, 12, 5, *, +, 40, 2, /, -]", InfixToPostfix.convert("3*20+12*5-40/2").toString()); + + Assert.assertEquals("[10, 2, 3, *, -, 50, +]", InfixToPostfix.convert("10-2*3+50").toString()); + + Assert.assertEquals("[3, 20, 2, /, *]", InfixToPostfix.convert("3*20/2").toString()); + + Assert.assertEquals("[10, 30, 50, +, -]", InfixToPostfix.convert("10-30+50").toString()); + + Assert.assertEquals("[20, 2, 3, *, /]", InfixToPostfix.convert("20/2*3").toString()); + + } +} diff --git a/group09/610673813/src/coding/week07/test/PostfixExprTest.java b/group09/610673813/src/coding/week07/test/PostfixExprTest.java new file mode 100644 index 0000000000..4e1bda4b42 --- /dev/null +++ b/group09/610673813/src/coding/week07/test/PostfixExprTest.java @@ -0,0 +1,37 @@ +package coding.week07.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week07.basic.PostfixExpr; + +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/group09/610673813/src/coding/week07/test/PrefixExprTest.java b/group09/610673813/src/coding/week07/test/PrefixExprTest.java new file mode 100644 index 0000000000..2135a2634c --- /dev/null +++ b/group09/610673813/src/coding/week07/test/PrefixExprTest.java @@ -0,0 +1,43 @@ +package coding.week07.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week07.basic.PrefixExpr; + +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/group09/610673813/src/coding/week08/basic/CircleQueue.java b/group09/610673813/src/coding/week08/basic/CircleQueue.java new file mode 100644 index 0000000000..cbdbf03e90 --- /dev/null +++ b/group09/610673813/src/coding/week08/basic/CircleQueue.java @@ -0,0 +1,53 @@ +package coding.week08.basic; + +import java.util.Arrays; + +/** + * 用数组实现循环队列 + * @author gallenzhang + * + * @param + */ +public class CircleQueue { + private final static int DEFAULT_SIZE = 10; + + // 用数组来保存循环队列的元素 + private Object[] elementData = new Object[DEFAULT_SIZE]; + + //队列的长度 + private int size; + // 队头 + private int front = 0; + // 队尾 + private int rear = 0; + + public boolean isEmpty() { + return front == rear; + } + + public int size() { + return size; + } + + public void enQueue(E data) { + if((rear + 1) % elementData.length == front){ + int len = elementData.length + elementData.length / 2; + elementData = Arrays.copyOf(elementData, len); + } + elementData[rear] = data; + size++; + rear = (rear + 1) % elementData.length; + } + + @SuppressWarnings("unchecked") + public E deQueue() { + if(isEmpty()){ + return null; + } + + E e = (E) elementData[front]; + front = (front + 1) % elementData.length; + size--; + return e; + } +} diff --git a/group09/610673813/src/coding/week08/basic/Josephus.java b/group09/610673813/src/coding/week08/basic/Josephus.java new file mode 100644 index 0000000000..ac24202671 --- /dev/null +++ b/group09/610673813/src/coding/week08/basic/Josephus.java @@ -0,0 +1,40 @@ +package coding.week08.basic; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用Queue来实现Josephus问题 在这个古老的问题当中, N个深陷绝境的人一致同意用这种方式减少生存人数: N个人围成一圈(位置记为0到N-1), + * 并且从第一个人报数, 报到M的人会被杀死, 直到最后一个人留下来 该方法返回一个List, 包含了被杀死人的次序 + * + * @author gallenzhang + * + */ +public class Josephus { + + public static List execute(int n, int m) { + Queue allQueue = new Queue<>(); + Queue killQueue = new Queue<>(); + for(int i = 0; i < n; i++){ + allQueue.enQueue(i); + } + + int k = 0; + while(!allQueue.isEmpty()){ + Integer num = allQueue.deQueue(); + k++; + if(k == m){ + killQueue.enQueue(num); + k = 0; + }else{ + allQueue.enQueue(num); + } + } + List killList = new ArrayList<>(); + while(!killQueue.isEmpty()){ + killList.add(killQueue.deQueue()); + } + + return killList; + } +} diff --git a/group09/610673813/src/coding/week08/basic/Queue.java b/group09/610673813/src/coding/week08/basic/Queue.java new file mode 100644 index 0000000000..dc4fd42999 --- /dev/null +++ b/group09/610673813/src/coding/week08/basic/Queue.java @@ -0,0 +1,54 @@ +package coding.week08.basic; + +import java.util.NoSuchElementException; + +public class Queue { + private Node first; + private Node last; + private int size; + + private static class Node { + private E item; + private Node next; + } + + public Queue() { + first = null; + last = null; + size = 0; + } + + public boolean isEmpty() { + return first == null; + } + + public int size() { + return size; + } + + public void enQueue(E data) { + Node oldlast = last; + last = new Node(); + last.item = data; + last.next = null; + if (isEmpty()) { + first = last; + } else { + oldlast.next = last; + } + size++; + } + + public E deQueue() { + if (isEmpty()) { + throw new NoSuchElementException("Queue underflow"); + } + E item = first.item; + first = first.next; + size--; + if (isEmpty()) { + last = null; + } + return item; + } +} diff --git a/group09/610673813/src/coding/week08/basic/QueueWithTwoStacks.java b/group09/610673813/src/coding/week08/basic/QueueWithTwoStacks.java new file mode 100644 index 0000000000..004e633e51 --- /dev/null +++ b/group09/610673813/src/coding/week08/basic/QueueWithTwoStacks.java @@ -0,0 +1,46 @@ +package coding.week08.basic; + +import java.util.Stack; + +/** + * 用两个栈来实现一个队列 + * + * @author gallenzhang + * + * @param + */ +public class QueueWithTwoStacks { + private Stack stack1; + private Stack stack2; + + public QueueWithTwoStacks() { + stack1 = new Stack(); + stack2 = new Stack(); + } + + public boolean isEmpty() { + return stack1.size() == 0; + } + + public int size() { + return stack1.size(); + } + + public void enQueue(E item) { + stack1.push(item); + } + + public E deQueue() { + if(stack1.isEmpty()){ + return null; + } + while(!stack1.isEmpty()){ + stack2.push(stack1.pop()); + } + E e = stack2.pop(); + while(!stack2.isEmpty()){ + stack1.push(stack2.pop()); + } + return e; + } +} diff --git a/group09/610673813/src/coding/week08/test/CircleQueueTest.java b/group09/610673813/src/coding/week08/test/CircleQueueTest.java new file mode 100644 index 0000000000..3597be30fe --- /dev/null +++ b/group09/610673813/src/coding/week08/test/CircleQueueTest.java @@ -0,0 +1,41 @@ +package coding.week08.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week08.basic.CircleQueue; + + +public class CircleQueueTest { + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void test() { + CircleQueue queue = new CircleQueue(); + Assert.assertTrue(queue.isEmpty()); + + queue.enQueue("a"); + queue.enQueue("b"); + queue.enQueue("c"); + queue.enQueue("d"); + queue.enQueue("e"); + + Assert.assertFalse(queue.isEmpty()); + Assert.assertEquals(5, queue.size()); + + Assert.assertEquals("a", queue.deQueue()); + Assert.assertEquals("b", queue.deQueue()); + Assert.assertEquals("c", queue.deQueue()); + Assert.assertEquals("d", queue.deQueue()); + Assert.assertEquals("e", queue.deQueue()); + + } +} diff --git a/group09/610673813/src/coding/week08/test/JosephusTest.java b/group09/610673813/src/coding/week08/test/JosephusTest.java new file mode 100644 index 0000000000..da2887b701 --- /dev/null +++ b/group09/610673813/src/coding/week08/test/JosephusTest.java @@ -0,0 +1,26 @@ +package coding.week08.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import coding.week08.basic.Josephus; + +public class JosephusTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testExecute() { + + Assert.assertEquals("[1, 3, 5, 0, 4, 2, 6]", Josephus.execute(7, 2).toString()); + + } +}