学习使用Java制作简易计算器的第二天
在配置完JFormDesigner(不会的小伙伴可以查看我的第一天如何配置JFormDesigner,虽比较繁琐,但为了详细和能够成功总要点时间的嘛.)
我先制作的是简易计算器的算法,大概制作完成能够实现加减乘除,括号,小数以及负号运算。
算法分析
个人比较菜,接下来有什么不对的地方,希望厉害的大佬能多多包涵,也希望大佬能够提出您宝贵的意见(非常想从您那学习java知识)!
①先转为后缀表达式,目的是为了清除括号
比如说 A + (B - C / D) * E
这里因为还有小数点的原因,我将小数点与数字当成是一样的,最后能形成的效果,是形成后缀表达式,并将符号和数字分开,最后因为去掉括号和合并数和小数点,用“#”代替,之后只要遍历到#,那么就说明字符串结束了。
②接下来的思想,就是如何计算了。
`package com.braden.exp1;
import java.util.Stack;
class Calculate {
static Stack<Character> op = new Stack<>();
char[] operator = {'+', '-', '*', '/', '(', ')'};
int[][] perior = {
{1, 1, -1, -1, -1, 1},
{1, 1, -1, -1, -1, 1},
{1, 1, 1, 1, -1, 1},
{1, 1, 1, 1, -1, 1},
{-1, -1, -1, -1, -1, 0},
{1, 1, 1, 1, 0, 1},
};
public String[] convertArray(char[] strArray) {
Stack<Character> opStack = new Stack<Character>();
int len = strArray.length;
int index = 0;
String keepNum = "";
char ch = ' ';
int arrIndex = 0;
String[] arr = new String[len] ;
//arr初始都赋值成"#"
for (int i = 0; i < len; i++) {
arr[i] = "#";
}
while (index <= len - 1) {
ch = strArray[index];
//如果这是一个数
if (!isOper(ch) || ch == '.') {
keepNum += String.valueOf(ch);
//如果这个数刚好是最后一个字符
if (index == len - 1) {
arr[arrIndex] = keepNum;
arrIndex++;
} else {
//如果下一个字符是操作符的话,就可以将这个keepNum入数组了
if (isOper(strArray[index + 1])) {
arr[arrIndex] = keepNum;
keepNum = "";
arrIndex++;
}
}
} else {
//这里是如果字符是操作符的话if (ch == '-' && index == 0)
if (ch == '-' && index == 0) {
keepNum += String.valueOf(ch);//第一个符号是负号
} else if (ch == '-') {
Boolean flag = false;
int p = index-1;
while ((strArray[p] == '(' || strArray[p] == ')') && p > 0) {
p--;
}
//-前面是操作符,说明是负号
if (isOper(strArray[p])) {
keepNum += String.valueOf(ch);
} else {
while (!opStack.empty()) {
if (perior[getPos(opStack.peek())][getPos(ch)] == 1) {
arr[arrIndex] = String.valueOf(opStack.pop());
arrIndex ++;
} else {
break;
}
}
opStack.push(ch);
}
} else if (opStack.empty()) {
opStack.push(ch);//栈为空直接压入栈
} else if(ch == '(') {
opStack.push(ch);
} else if (ch == ')') {
while (opStack.peek() != '(') {
arr[arrIndex] = String.valueOf(opStack.pop());
arrIndex ++;
}
opStack.pop();
} else {
//栈的顶端优先级比ch大
while (!opStack.empty()) {
if (perior[getPos(opStack.peek())][getPos(ch)] == 1) {
arr[arrIndex] = String.valueOf(opStack.pop());
arrIndex ++;
} else {
break;
}
}
opStack.push(ch);
}
}
index ++;
}
while (!opStack.empty()) {
arr[arrIndex] = String.valueOf(opStack.pop());
arrIndex ++;
}
//将栈中全部的操作符出栈
return arr;
}
public float getValue (String[] postfixArray) {
float ans = 0;
int len = postfixArray.length;
float num1 = 0;
float num2 = 0;
float num = 0;
Stack<Float> numStack = new Stack<>();
Stack<Character> opStack = new Stack<>();
for (int i = 0; i < len; i++) {
//如果是#代表结束,后缀栈中无数和操作符
if (postfixArray[i] == "#") {
break;
}
//检测是否是操作符,如果是负数,取出的第一个也是符号,所以要判断取出的字符串长度为1才行
if (isOper(postfixArray[i].charAt(0)) && postfixArray[i].length() == 1) {
num2 = numStack.pop();
num1 = numStack.pop();
num = calValue(postfixArray[i].charAt(0), num1, num2);
numStack.push(num);
} else {
//如果是数的话,就压入数栈
numStack.push(Float.valueOf(postfixArray[i]));
}
}
ans = numStack.pop();
return ans;
}
private float calValue(char ch, float num1, float num2) {
switch (ch) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
return num1 / num2;
default:
return 0;
}
}
private boolean isOper(char ch) {
return ch == '*' || ch == '/' || ch == '+' || ch == '-' || ch == '(' || ch == ')';
}
private int getPos(char ch) {
switch (ch) {
case '+':
return 0;
case '-':
return 1;
case '*':
return 2;
case '/':
return 3;
case '(':
return 4;
case ')':
return 5;
default:
return -1;
}
}
}
`
如果有什么不对的地方,请大家多多指正!