java实现计算器_java高级计算器的实现

不仅可以实现+,-,*,/,( ,) ,log ,ln,√ , ^ , cos ,sin,tan ,还支持最大500长度的字符运算。本程序是我上课的时候老师讲的,可能不是老师的原创,希望对有些同学有用,不扯了,上图:

import java.text.DecimalFormat;

import java.util.StringTokenizer;

/**

* 计算器的核心内容:

* 1.计算部分:必须建立在无错误的结论下

*2.数据格式化

*3.阶乘算法

*4.错误提示

* @author asus

*

*/

public class Calc {

//设定最大的运算符长度

private static final int MAXLEN = 500 ;

/**

* 计算表达式的字符串形式

* 从左到右扫面,数字先入number栈,运算符入operator栈

* +-基本优先级为1 *÷的优先级为2,log ln sin cos tan n!的优先级为3,开方,乘方的优先级为4

* 括号内存运算法的优先级高于4

* 当前运算符优先级高于栈顶压栈,低于栈顶弹出一个运算符与两个数字进行运算

* 重复直到运算符大于栈顶

* 扫面完之后对剩下的运算符与数字依次进行计算

* @param str

*/

public static void process(String str , boolean drag_flag){

int weightPlus = 0 ; //记录同一个()的基本优先级

int topTop = 0 ; //数组计数器

int topNum = 0 ;

int flag =1 ; //判断正负 1为正数 -1为负数

int weightTemp = 0 ; //记录临时优先级的变化

int weight[] = new int[MAXLEN];

double[] number = new double[MAXLEN] ;

char ch , ch_gai , operator[] = new char[MAXLEN] ;

String num ; // 记录数字 str将以+-×÷()sctgl!√ ^分割,字符串之间即为数字

String experssion = str ;

StringTokenizer expToken = new StringTokenizer(experssion, "+-×÷()sctgl!√ ^");

int i =0 ;

while(i

ch = experssion.charAt(i);

//判断正负数

if(i==0){

if(ch == '-'){

flag = -1 ;

}

}else if(experssion.charAt(i-1)=='(' && ch == '-')

flag = -1 ;

//取得数字,将正负号交给该数字

if(ch>='0' && ch<='9' || ch=='.'|| ch=='E'){

num = expToken.nextToken();

ch_gai = ch ;

while(i= '0' && ch_gai <= '9' || ch_gai == '.' || ch_gai == 'E')){

ch_gai = experssion.charAt(i++);

System.out.println("i的值为:"+i+" , ch_gai的值为:"+ch_gai);

}

if(i >= experssion.length())i-=1 ;

else i-=2 ;

if(num.compareTo(".") == 0) number[topNum++] = 0 ;

else {

number[topNum++] = Double.parseDouble(num)*flag ;

flag = 1 ;

}

}

//计算运算符的优先级

if(ch=='(') weightPlus += 4 ;

if(ch==')') weightPlus -= 4;

if(ch=='-' && flag == 1 || ch == '+' || ch == '-' || ch == '×' || ch == '÷' ||

ch == 's' || ch == 'c' || ch == 't' || ch == 'l' || ch == 'g' || ch == '!' || ch == '√' || ch == '^'){

switch(ch){

//+-的优先级最低

case '+':

case '-':

weightTemp = weightPlus + 1 ;

break;

//×÷的优先级为2

case '÷':

case '×':

weightTemp = weightPlus + 2 ;

break;

case 's':

case 'c':

case 't':

case 'l':

case 'g':

case '!':

weightTemp = weightPlus + 3 ;

break;

case '√':

case '^':

default:

weightTemp = weightPlus + 4 ;

break;

}

//如果当前优先级大于栈顶的元素,则直接入栈

if(topTop == 0 || weight[topTop -1] < weightTemp){

weight[topTop] = weightTemp;

operator[topTop] = ch ;

System.out.println("============"+ch+"========");

topTop++ ;

}else{ //否则将堆栈中的运算符逐个取出,直到当前栈顶部运算符的优先级小于当前运算符

while(topTop>0 && weight[topTop-1] > weightTemp){

switch(operator[topTop-1]){

case '+':

number[topNum-2] += number[topNum-1];

break;

case '-':

number[topNum-2]-=number[topNum-1];

break;

case '×':

number[topNum-2] *= number[topNum-1];

break;

case '÷':

if(number[topNum-1] == 0){

System.out.println("0不能为除数");

return ;

}

number[topNum-2] /= number[topNum-1];

break;

case '√':

//负值不能开偶次方

if(number[topNum-1] == 0 || (number[topNum-2] < 0 && number[topNum-1] % 2 == 0)){

System.out.println("平方数不存在或者负数不能开偶次行!");

return ;

}

number[topNum-2] = Math.pow(number[topNum-1], 1/number[topNum-2]);

break;

case '^':

number[topNum-2] = Math.pow(number[topNum-2], number[topNum-1]);

break;

case 's':

//角度

if(drag_flag){

number[topNum-1] = Math.sin(number[topNum-1]*Math.PI/180);

}else{

//此时为弧度

number[topNum-1] = Math.sin(number[topNum-1]);

}

topNum ++ ;

break;

case 'c':

if(drag_flag){

number[topNum-1] = Math.cos(number[topNum-1]*Math.PI/180);

}else{

number[topNum-1] = Math.cos(number[topNum-1]);

}

topNum++;

break;

case 't':

if(drag_flag){

if(Math.abs(number[topNum-1]%90) == 1){

System.out.println("tan取值有错误");

return;

}

number[topNum-1] = Math.tan(number[topNum-1]*Math.PI/180);

}else{

if(Math.abs(number[topNum-1] % Math.PI * 2) ==1){

System.out.println("tan取值有错误");

return;

}

number[topNum-1] = Math.tan(number[topNum-1]);

}

topNum++;

break;

//ln

case 'l':

if(number[topNum-1]<=0){

System.out.println("对数ln值有误");

return;

}

number[topNum-1] = Math.log(number[topNum-1]);

topNum++;

break;

//log

case 'g':

if(number[topNum-1]<=0){

System.out.println("对数log值有误");

return;

}

number[topNum-1] = Math.log10(number[topNum-1]);

topNum++;

break;

case '!':

if(number[topNum-1]<0){

System.out.println("阶乘数有误");

return ;

}

number[topNum-1] = getN(number[topNum-1]);

topNum++;

break;

}

//继续堆栈下一个元素判断

topNum -- ;

topTop -- ;

}

//将运算符压入栈中

weight[topTop] = weightTemp ;

operator[topTop] = ch ;

topTop++ ;

}

}

i++ ;

}

//依次取出堆运算中的运算符进行运算

while(topTop>0){

//直接将数组的后两位取出运算

switch(operator[topTop-1]){

case '+':

number[topNum-2] += number[topNum-1];

break;

case '-':

number[topNum-2] -= number[topNum-1];

break;

case '×':

number[topNum-2] *= number[topNum-1];

break;

case '÷':

if(number[topNum-1] == 0){

System.out.println("0不能为除数");

return ;

}

number[topNum-2] /= number[topNum-1];

break;

case '√':

//负值不能开偶次方

if(number[topNum-1] == 0 || (number[topNum-2] < 0 && number[topNum-1] % 2 == 0)){

System.out.println("平方数不存在或者负数不能开偶次方!");

return ;

}

number[topNum-2] = Math.pow(number[topNum-1], 1/number[topNum-2]);

break;

case '^':

number[topNum-2] = Math.pow(number[topNum-2], number[topNum-1]);

break;

case 's':

//角度

if(drag_flag){

number[topNum-1] = Math.sin(number[topNum-1]*Math.PI/180);

}else{

//此时为弧度

number[topNum-1] = Math.sin(number[topNum-1]);

}

topNum ++ ;

break;

case 'c':

if(drag_flag){

number[topNum-1] = Math.cos(number[topNum-1]*Math.PI/180);

}else{

number[topNum-1] = Math.cos(number[topNum-1]);

}

topNum++;

break;

case 't':

if(drag_flag){

if(Math.abs(number[topNum-1]%90) == 1){

System.out.println("tan取值有错误");

return;

}

number[topNum-1] = Math.tan(number[topNum-1]*Math.PI/180);

}else{

if(Math.abs(number[topNum-1] % Math.PI * 2) ==1){

System.out.println("tan取值有错误");

return;

}

number[topNum-1] = Math.tan(number[topNum-1]);

}

topNum++;

break;

//ln

case 'l':

if(number[topNum-1]<=0){

System.out.println("对数ln值有误");

return;

}

number[topNum-1] = Math.log(number[topNum-1]);

topNum++;

break;

//log

case 'g':

if(number[topNum-1]<0){

System.out.println("对数log值有误");

return;

}

number[topNum-1] = Math.log10(number[topNum-1]);

topNum++;

break;

case '!':

if(number[topNum-1]<0){

System.out.println("阶乘数有误");

return ;

}

number[topNum-1] = getN(number[topNum-1]);

topNum++;

break;

}

//取下一个元素计算

topNum -- ;

topTop -- ;

}

if(number[0]>7.3E306){

System.out.println("计算数组过大");

return ;

}

//数据显示:

System.out.println("最终计算答案为:"+dataShow(number[0]));

}

private static double getN(double n){

if(n==0)

return 1;

double sum = 1.0;

for(int s = 1 ; s <= n ; s++){

sum *= s ;

}

return sum ;

}

private static String dataShow(double n){

DecimalFormat format = new DecimalFormat("0.############");

return format.format(n).toString();

}

public static void main(String[] args) {

process("16+(7×l7)-90×g23+(1÷2)" ,true);

}

}

由于比较懒,log就用g代替,ln就用l,sin用sin代替,cos用o代替,tan用t代替,不过这都不是重点,重点是这种处理的思想和方案.希望对大家有用,当然如果你喜欢,完全可以改一下做成一个android的应用,呵呵,我就做了一个,但是个人感觉本实验对android来说,并不是很优秀的算法,因为在每次输入的情况,都会对输入的字符串检测是否合法,显然对运算能力较弱的android来说有点吃力,不过,谁叫android也用java写呢????呵呵

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值