一个简单的计算器功能,因为没事做随便写了下,所以写的垃圾代码比较多,形成了一座“大屎山”,如果正常写的话,完全可以用最后一步将输入数字以及操作符放在栈中进行操作,当select=3时的代码会有一些帮助,输入格式都是带空格的,这里面也包含了一些其他功能:
1.存储最近计算结果
2.浏览所有计算历史
3.根据id查找结果
4.清空历史记录
5.与最近计算结果进行二次运算(支持(opera n)形式)
6.进行带括号运算(但只支持(n opera n) opera (n opera n)形式)
7.包含很多对于输入格式不正确的异常捕捉
我们废话不多说直接上代码吧
public class Calculator {
String expre; //表达式
int type = 0; //表达式是double型运算还是int型运算,type为0,int;为1,double
int div0 = 0; //evaluate中div0>0,则第二个数字为0
int div1 = 0; //evalua1中判断除数是否为0
double recent = 0; //最近存储
public static ArrayList list = new ArrayList<>(); //集合声明,存储列表
float result = 0;
double firstDouble;
double secondDouble;
//构造函数初始化
public Calculator() {
} //创建存储列表
public Calculator(String expre) {
this.expre = expre;
}
//判断表达式是否合法
public float evaluate(String expression) {
//以空格为分界符分割
String[] str = expression.split(" ");
//判断str数组长度,不等于3,则error
if (str.length != 3) {
System.out.println("Invaild input.");
return Float.MIN_VALUE;
}
//判断是浮点型还是整形
int flag = 0; //标志位,判断是否有小数点,flag=0,则为int
char[] num1 = str[0].toCharArray(); //第一数字字符串,检查是否有小数点
for (int i = 0; i < num1.length; i++) {
if (num1[i] == '.') {
flag++;
}
}
char[] num2 = str[2].toCharArray(); //第二数字字符串,检查是否有小数点
for (int i = 0; i < num2.length; i++) {
if (num2[i] == '.') {
flag++;
}
}
//判断flag
if (flag == 0) {
type = 0;
} else {
type = 1;
}
//转换为数字
//将字符串转换成double形式,若错误输入如:9@ + 9等等,会报错,所以采用异常处理
try {
firstDouble = Double.parseDouble(str[0]);
secondDouble = Double.parseDouble(str[2]);
} catch (Exception ex) { //若转换出现异常,则报错
System.out.println("Invaild input.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
if (secondDouble == 0) {
div0++; //判断第二个数字是否为0
}
//判断运算符是否有效 and 计算结果,暂时都是double型
switch (str[1]) {
case "+": {
result = (float) (firstDouble + secondDouble);
break;
}
case "-": {
result = (float) (firstDouble - secondDouble);
break;
}
case "*": {
result = (float) (firstDouble * secondDouble);
break;
}
case "/": {
if (div0 != 0) { //判断第二个数字是否为0
System.out.println("Invaild input.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
} else {
result = (float) (firstDouble / secondDouble);
break;
}
}
default: {
System.out.println("Invaild input.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
}
return 1;
}
//返回运行结果
public float getCurrentValue() {
if (type == 0) { //int型输出
int FianlResult = (int) (result);
System.out.println("运算结果为" + FianlResult);
return FianlResult;
} else { //double型输出
System.out.println("运算结果为" + result);
return (float) (result);
}
}
//设置最近存储结果
public void setMemoryValue(float memval) {
recent = memval;
list.add(recent);
//System.out.println("历史记录为"+list);
}
//清空列表
public void clearMemory() {
list.clear();
}
//获取全部存储结果
public float getMemoryValue() {
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i));
System.out.print(" ");
}
return 0;
}
//获得某个存储结果
public float getHistoryValue(int index) {
try { //可能出现数组越界,有异常捕捉
System.out.println(list.get(index));
} catch (Exception ex) {
System.out.println("数组越界,输入错误");
}
return 0;
}
//再次计算
public float evaluate1(String expression1, float m) {
String[] str1 = expression1.split(" ");
if (str1.length != 2) {
System.out.println(expression1);
System.out.println("Invaild input.");
return Float.MIN_VALUE;
}
//判断是浮点型还是整形
int flag = 0; //标志位,判断是否有小数点,flag=0,则为int
char[] num1 = str1[1].toCharArray();
for (int i = 0; i < num1.length; i++) {
if (num1[i] == '.') {
flag++;
}
}
//判断flag
if (flag == 0) {
type = 0;
} else {
type = 1;
}
try {
firstDouble = Double.parseDouble(str1[1]);
} catch (Exception ex) { //若转换出现异常,则报错
System.out.println("Invaild input.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
if (firstDouble == 0) {
div1++; //判断第二个数字是否为0
}
//判断运算符是否有效 and 计算结果,暂时都是double型
switch (str1[0]) {
case "+": {
result = (float) (firstDouble + m);
break;
}
case "-": {
result = (float) (m - firstDouble);
break;
}
case "*": {
result = (float) (firstDouble * m);
break;
}
case "/": {
if (div1 != 0) { //判断第二个数字是否为0
System.out.println("Invaild input.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
} else {
result = (float) (m / firstDouble);
break;
}
}
default: {
System.out.println("Invaild input.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
}
return result;
}
//带括号计算
public float evaluate2(String expression) {
//以空格为分界符分割
String[] str = expression.split(" ");
//判断str数组长度,不等于7,则error
//System.out.println(str.length);
if (str.length != 7) {
System.out.println("Invaild input1.");
return Float.MIN_VALUE;
}
//处理括号
str[0] = str[0].substring(1);
str[2] = str[2].substring(0, str[2].length() - 1);
String opera = str[3];
str[4] = str[4].substring(1);
str[6] = str[6].substring(0, str[6].length() - 1);
//转换为数字
//将字符串转换成double形式,若错误输入如:9@ + 9等等,会报错,所以采用异常处理
try {
firstDouble = Double.parseDouble(str[0]);
secondDouble = Double.parseDouble(str[2]);
} catch (Exception ex) { //若转换出现异常,则报错
System.out.println("Invaild input2.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
//System.out.println(str[1]);
//判断运算符是否有效 and 计算结果,暂时都是double型
switch (str[1]) {
case "+": {
result = (float) (firstDouble + secondDouble);
break;
}
case "-": {
result = (float) (firstDouble - secondDouble);
break;
}
case "*": {
result = (float) (firstDouble * secondDouble);
break;
}
case "/": {
if (div0 != 0) { //判断第二个数字是否为0
System.out.println("Invaild input3.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
} else {
result = (float) (firstDouble / secondDouble);
break;
}
}
default: {
System.out.println("Invaild input5.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
}
float r1 = result;
//处理第二个表达式
try {
firstDouble = Double.parseDouble(str[4]);
secondDouble = Double.parseDouble(str[6]);
} catch (Exception ex) { //若转换出现异常,则报错
System.out.println("Invaild input2.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
//判断运算符是否有效 and 计算结果,暂时都是double型
switch (str[5]) {
case "+": {
result = (float) (firstDouble + secondDouble);
break;
}
case "-": {
result = (float) (firstDouble - secondDouble);
break;
}
case "*": {
result = (float) (firstDouble * secondDouble);
break;
}
case "/": {
if (div0 != 0) { //判断第二个数字是否为0
System.out.println("Invaild input3.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
} else {
result = (float) (firstDouble / secondDouble);
break;
}
}
default: {
System.out.println("Invaild input4.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
}
float r2 = result;
switch (opera) {
case "+": {
result = r1 + r2;
break;
}
case "-": {
result = r1 - r2;
break;
}
case "*": {
result = r1 * r2;
break;
}
case "/": {
if (div0 != 0) { //判断第二个数字是否为0
System.out.println("Invaild input3.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
} else {
result = r1 / r2;
break;
}
}
default: {
System.out.println("Invaild input5.");
return Float.MIN_VALUE;//若不合法,则输出MIN_VALUE
}
}
System.out.println("运算结果为:" + result);
return result;
}
}
class Homework {
//main 函数
public static void main(String[] args) {
Stack s1 = new Stack<>();//运算栈
Stack s2 = new Stack<>();//中间结果栈
Stack s3 = new Stack<>();
Calculator c = new Calculator();//存储对象,用来存储计算记录
float m = 0; //存储最近一次计算结果
while (true) {
System.out.println();
System.out.println("输入表达式:");
Scanner input = new Scanner(System.in);
String expression = input.nextLine(); //输入带空格表达式
System.out.println("选择模式:(1-不带括号的简单运算,2-带括号的多值运算,3-不带括号的多值运算)");
int select = input.nextInt();
if (select == 2) {
Calculator d = new Calculator(expression);
m = d.evaluate2(expression);
} else if (select == 1) {
Calculator d = new Calculator(expression);
double Isok = d.evaluate(expression); //判断是否有效
if (Isok == 1) { //有效继续
m = d.getCurrentValue(); //返回计算结果
}
} else if (select == 3) {
String[] opera = expression.split(" ");
//System.out.println(opera.length);
for (int i = 0; i < opera.length; i++) {
if (i % 2 == 0) {
try {
float temp = Float.parseFloat(opera[i]);
s2.push(temp);
} catch (Exception ex) {
System.out.println("Input Illegelly");
}
} else {
if (s1.isEmpty()) {
s1.push(opera[i]);
} else if ((opera[i].equals("*") || opera[i].equals("/") && (s1.peek().equals("+") || s1.peek().equals("-")))) {
s1.push(opera[i]);
} else {
s2.push(s1.pop());
i--;
}
}
}
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
while (!s2.isEmpty()) {
s1.push(s2.pop());
}
while (!s1.isEmpty()) {
String op = "";
float result = 0;
try {
op = s1.pop().toString();
float temp = Float.parseFloat(op);
s3.push(temp);
} catch (Exception exception) {
float op1 = Float.parseFloat(s3.pop().toString());
float op2 = Float.parseFloat(s3.pop().toString());
switch (op) {
case "+": {
result = op2 + op1;
break;
}
case "-": {
result = op2 - op1;
break;
}
case "*": {
result = op1 * op2;
break;
}
case "/": {
result = op2 / op1;
break;
}
}
s3.push(result);
}
}
m = (float) (s3.pop());
System.out.println(m);
}
System.out.println("解下来的操作(m-存储、c-清空、mr-历史结果、h-查找、over-结束任务):");
Scanner next = new Scanner(System.in);
String key = next.next(); //输入接下来的操作
switch (key) {
case "m": {
c.setMemoryValue(m); //存储并且选择实现第二次运算
System.out.println("接下来的操作(i-输入表达式、n-取消):");
String n = input.next();
switch (n) {
case "n": {
continue;
} //不进行运算
case "i": { //进行运算并输入表达式
System.out.println("上一次运算结果为" + m);
System.out.println("输入表达式(operator[space]operand):");
Scanner input1 = new Scanner(System.in);
String expression1 = input1.nextLine();
float k = c.evaluate1(expression1, m); //返回结果
if (k != Float.MIN_VALUE) {
System.out.println("运算结果为" + k);
}
break;
}
}
break;
}
case "c": {
c.clearMemory();
break;
} //清空
case "mr": {
c.getMemoryValue();
break;
}
case "h": {
System.out.println("选择你想要查找的id:");
int id = next.nextInt(); //输入想要查找的id
c.getHistoryValue(id);
break;
}
case "over": {
return;
}
default: {
System.out.println("Invaild input.");
}
}
}
}
}
运行效果图
以上代码可以改进的地方很多,各位朋友可以自行进行代码优化,我比较懒,我就不不做任何优化了
评论区