日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java四则运算器算法_java写的四则运算器

發(fā)布時間:2024/4/14 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java四则运算器算法_java写的四则运算器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本打算做一個從RE到NFA的轉(zhuǎn)換器,思路已經(jīng)理清了,但是在動手做的時候,遇到了很多問題,有些技術(shù)難點都遺忘了,包括如何定義閉包,如何利用遞歸來實現(xiàn)。?于是回頭重新拾起這些技術(shù),邊學(xué)邊思考,做了個四則運算器練練手,為著那個大目標(biāo)做準(zhǔn)備。

基本的思路是這樣的:?根據(jù)輸入的四則運算表達式,生成一棵二叉樹,樹的根節(jié)點是操作符,而子樹可能是葉子節(jié)點,即數(shù)字。也可能是另一個運算表達式。生成樹的規(guī)則是,對每一個節(jié)點產(chǎn)生一個相應(yīng)的type值,type值越大,就在樹的越靠上節(jié)點。基本原則是: 數(shù)字(10) < 乘除運算(20) < 加減運算(30)。?括號被當(dāng)做是一種特殊的符號,并不會在二叉樹上顯示出來,相應(yīng)的,它會影響到在括號內(nèi)出現(xiàn)符號的type值,每嵌套一層括號,就會將type值減少100, 這樣確保了括號內(nèi)的內(nèi)容在樹的最底層。?當(dāng)二叉樹構(gòu)造好了之后,利用遞歸,將左樹的計算結(jié)果與右樹的結(jié)果,根據(jù)根操作符計算出結(jié)果。?舉例:10?生成樹只有一個節(jié)點,同時也是根節(jié)點,返回值便是根節(jié)點值。?舉例: 10 + 2首先生成根節(jié)點為10,但當(dāng)讀入+時,+的type值比10高,因此上移,并成為新的跟節(jié)點,最后加入2,因為2比+type值小,因此作為右子節(jié)點。?舉例: 10 + 2 * 5當(dāng)讀入*時,*的type值比2大,因此上移,同時又比+的type值小,因此就在+與2之間插入新的節(jié)點。?舉例: 10 + 2 *(2 + 3)當(dāng)讀入(時,后面所產(chǎn)生的所有Node的type值會相應(yīng)的-100, 因此括號內(nèi)的+的type值就會比外面的*小,但是仍然比括號內(nèi)的數(shù)字大,這樣保證了在樹中,2+3會先執(zhí)行。當(dāng)讀入)時,offset清零。

public class Main { public static void main(String[] args) {

String exp = "(10 + 15) * 3 - 20 * 6 /5 - (8 + 14(2- 1))2 + 11(12 - 11)5";

//String exp = "12";

Main main = new Main();

Main.index = 0;

char[] input = main.prepare(exp.toCharArray());

System.out.println(main.cal(input)); }

/**

* Actual calculate method.

* @param exp

* @return

*/ public int cal(char[] exp) {

Node root = buildTree(exp);

return calculate(root); }

/**

* Prepare the exp, remove empty space or \n.

* Also the method will add losing * in below cases:

* 10(3-1)

---->

10*(3-1)

* (3-1)10

---->

(3-1)*10

*

* @param exp

* @return

*/ public char[] prepare(char[] exp) {

char[] worklist = new char[exp.length];

int j = 0;

for (int i = 0; i < exp.length; i++) {

char c = exp[i];

if (c == ' ' || c == '\n') {

continue;

} else {

if (c == '(') { // Handle the abbreviated * for (

if(j == 0 || isCalculator(worklist[j - 1])) {

//Do nothing.

} else {

worklist[j++] = '*';

}

worklist[j++] = c;

} else if (c == ')') {// Handle the abbreviated * for )

worklist[j++] = c;

while((i == exp.length - 1) || (exp[++i] == ' ')) {

//Do nothing.

}

if(isCalculator(exp[i]) || exp[i] == ')') {

//Do nothing.

} else {

worklist[j++] = '*';

}

i--;

} else {

worklist[j++] = c;

}

}

}

char[] result = new char[j];

System.arraycopy(worklist, 0, result, 0, j);

return result; }

/**

* Check if c is a calculator or not.

* @param c

* @return

*/ private boolean isCalculator(char c) {

if(c == '+' || c == '-' || c == '*' || c == '/') {

return true;

}

return false; }

/**

* Calculate the tree.

*

* @param node

* @return

*/ private int calculate(Node node) {

if(node.isLeaf()) return Integer.parseInt(node.value);

if(node.value.equals("+")) {

return calculate(node.leftChild) + calculate(node.rightChild);

} else if(node.value.equals("-")) {

return calculate(node.leftChild) - calculate(node.rightChild);

} else if(node.value.equals("*")) {

return calculate(node.leftChild) * calculate(node.rightChild);

}else {

return calculate(node.leftChild) / calculate(node.rightChild);

} }

/**

* Build a tree like this:

*

* 10 * (3 + 5)

*

* ------ 10

*

-

*

------ +

*

-

*

------- 3

*

------- 5

* @param exp

* @return

*/ private Node buildTree(char[] exp) {

Node root = null;

Node working = null;

while(true) {

Node node = readNext(exp);

if(node == null) break;

if(root == null) {

root = node;

working = node;

continue;

}

if(node.type > working.type) {

Node parent = working.parent;

boolean isLeft = false;

while(parent != null && node.type >= parent.type) {

isLeft = parent.isLeft;

working = parent;

parent = parent.parent;

}

if(parent == null) {

working.parent = node;

node.leftChild = working;

working.isLeft = true;

root = node;

} else {

Node tmp = isLeft ? parent.leftChild : parent.rightChild;

if(isLeft) {

parent.leftChild = node;

} else {

parent.rightChild = node;

}

node.isLeft = isLeft;

node.parent = parent;

tmp.parent = node;

node.leftChild = tmp;

tmp.isLeft = true;

}

} else {

working.rightChild = node;

node.isLeft = false;

node.parent = working;

}

working = node;

}

return root; }

private static int index = 0; // Read the next node, it possible to be a number, a calculator or just space. private Node readNext(char[] exp) {

if(index >= exp.length) return null;

Node node = new Node();

char c = exp[index++];

if(Character.isDigit(c)) {

node.type = Node.NUMBER + offset;

StringBuffer sb = new StringBuffer();

sb.append(c);

for(; index < exp.length; index++) {

char tmp = exp[index];

if(Character.isDigit(tmp)) {

sb.append(tmp);

} else {

break;

}

}

node.value = sb.toString();

} else if (c == '*' || c == '/') {

node.type = Node.MUL_DEL + offset;

node.value = Character.toString(c);

}else if (c == '+' || c == '-') {

node.type = Node.PLUS_MINUS + offset;

node.value = Character.toString(c);

} else if(c == '(') {

increaseOffset();

return readNext(exp);

}else if(c == ')') {

decreaseOffset();

return readNext(exp);

}

return node; }

// Every type in the embrace will have to add a offset as their type. private static int offset = 0; public static void increaseOffset() {

offset = offset - 100; }

public static void decreaseOffset() {

offset = offset + 100; }

/**

* Helping class.

*

*/ class Node {

private int type = 10;

private Node parent = null;

private Node leftChild = null;

private Node rightChild = null;

private boolean isLeft = false;

private String value = null;

public Node() {

}

public static final int NUMBER = 10;

public static final int MUL_DEL = 20;

public static final int PLUS_MINUS = 30;

public static final int EMBRACE = -100;

public boolean isLeaf() {

if(leftChild == null && rightChild == null) {

return true;

}

return false;

}

public int getType() {

return type;

}

public void setType(int type) {

this.type = type;

}

public Node getParent() {

return parent;

}

public void setParent(Node parent) {

this.parent = parent;

}

public Node getLeftChild() {

return leftChild;

}

public void setLeftChild(Node leftChild) {

this.leftChild = leftChild;

}

public Node getRightChild() {

return rightChild;

}

public void setRightChild(Node rightChild) {

this.rightChild = rightChild;

}

public boolean isLeft() {

return isLeft;

}

public void setLeft(boolean isLeft) {

this.isLeft = isLeft;

}

public String getValue() {

return value;

}

public void setValue(String value) {

this.value = value;

} }}

總結(jié)

以上是生活随笔為你收集整理的java四则运算器算法_java写的四则运算器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。