您的位置:首页 > 编程语言 > Java开发

每日20行之4~~~两种方法java实现简易计算器 附带复杂计算器代码(优先级顺序)

2015-08-12 00:36 696 查看
输入一行算式,每一个数字和运算符用空格隔开,例如“1 + 2 + 3 * 5 = “

其中不存在运算先后顺序,暂且不考虑,每日20行,之后慢慢实现,不可一口吃下一个胖子。 从左到右计算。

1. 第一种解决方法:

package 从零单排学Java;

import java.util.ArrayList;
import java.util.Scanner;

public class SimpleCalculator {
public static void main(String[] args) {
boolean whethercontinue = true;

ArrayList<String> formula = new ArrayList<String>();
while(whethercontinue){
System.out.println("Enter the formula:");
Scanner in = new Scanner(System.in);
String temp = "";
formula.add(in.next());
for(int i = 0;i<=formula.size();i++){
temp = formula.get(i);
String[] temp1 = temp.split(" ");
int[] count = null;
char[] operator = null;
for(int j = 0;j<(temp.length()/2);j++){
count = new int[temp.length()/2];
count[j] = Integer.parseInt(temp1[2*j]);
operator = new char[temp.length()/2];
operator[j] = temp1[2*j+1].charAt(0);
}
for(int l=0; l<count.length;l++){
if(operator[l]!='='){
if(operator[l]=='+') count[l+1]+=count[l];
else if(operator[l]=='-') count[l+1]+=count[l];
else if(operator[l]=='*') count[l+1]+=count[l];
else count[l+1]+=count[l];
}
else{
System.out.println("The calculation is finished.");
}
}
System.out.println("The result of the calculation is: "+count[count.length-1]);
}
System.out.println("Do you want to continue? If not, please input n.");
if(in.next()=="n"){
whethercontinue = false;
}
}
}
}


2. 第二种解决办法:

这种办法逻辑更为清晰,并没有用到数组。


package 从零单排学Java;

import java.util.Scanner;
public class Test1{
public static void main(String []args)
{
String s1_1,s1_2,s2;
Scanner in=new Scanner(System.in);
s1_1=in.next();
System.out.println(s1_1);
System.out.println("----------");
in.nextLine(); // 把剩余的吃掉
s2=in.nextLine();
System.out.println(s2);
System.out.println("----------");
s1_1=in.next();
s1_2=in.next();
System.out.println(s1_1+"       "+s1_2);
}
}
-------------------------------------------
*/
package 从零单排学Java;

import java.util.Scanner;
public class Test2{
public static void main(String args[]) {
int ri, repeat;
int op1, op2, res;
char operator;
Scanner in=new Scanner(System.in);
repeat=in.nextInt();
for(ri=1; ri<=repeat; ri++){
op1=in.nextInt();
operator =(in.next()).charAt(0);  //
res=op1;  //res看作最后的结果
while(operator!='=')
{
op2=in.nextInt();
if(operator=='+') res+=op2;


3. 复杂计算器的程序留着日后参考

package com.saturday;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyParse {
static Map optrOrder;
static {
optrOrder=new HashMap();
optrOrder.put("(", 0);
optrOrder.put("*", 1);
optrOrder.put("/", 1);
optrOrder.put("%", 1);
optrOrder.put("+",2);
optrOrder.put("-",2);
optrOrder.put("^",3);
optrOrder.put("#",3);
}

public static void main(String[] args){
List tokens;
try{
//词法分析
tokens=lex("+2* (-2+3*4)+-5");

//中缀转后缀
tokens=toRpn(tokens);

//计算结果
System.out.println(calcRpn(tokens));

}catch(Exception ex){
ex.printStackTrace();
}
}

/**
* 将输入串转换为操作符串
* @param sExpres
* @return
*/
public static List lex(String sExpres){
List tokens=new ArrayList();

//将表达式分割成符号序列
String sRegExp="(((?<=^|\\(|\\+|-|\\*|/|%)(\\+|-))?\\d+(\\.\\d+)?)"
+"|\\(|\\)|\\*|/|\\+|-";
Pattern p=Pattern.compile(sRegExp);
Matcher m=p.matcher(sExpres.replaceAll("\\s+",""));
while(m.find()){
tokens.add(m.group());
}

tokens.add("#");

return tokens;
}

/**
* 将中缀表单时转化为后缀表达式
* @param tokens
* @return
*/
public static List toRpn(List tokens)
throws Exception{
List  rpnList=new ArrayList();
Stack optrStack=new Stack();

optrStack.add("^");
for(String token:tokens){
if(token.matches("^(\\+|-)?\\d+(\\.\\d+)?$")){
rpnList.add(token);
}else{
outputOptr(token,optrStack,rpnList);
}
}

if(!optrStack.isEmpty()
&&optrStack.lastElement().equals("#")){
return rpnList;
}else{
throw new Exception("后缀表达式转化错误!");
}
}

/**
* 计算后缀表达式的值
* @param  rpnTokens
* @return
* @throws Exception
*/
public static double calcRpn(List rpnTokens)
throws Exception{
NumberFormat nf=NumberFormat.getInstance();
Stack numStack=new Stack();

for (String token : rpnTokens) {
if (token.matches("^(\\+|-)?\\d+(.\\d+)?$")) {
token=token.indexOf('+')==0
?token.substring(1)
:token;
numStack.add(nf.parse(token).doubleValue());
} else {
doCalcByOptr(token, numStack);
}
}

if (!numStack.isEmpty() && numStack.size() == 1) {
return numStack.lastElement();
} else {
throw new Exception("计算错误!");
}
}

/**
* 将运算符输出到后缀表达式序列.
* @param optr
* @param optrStack
* @param rpnList
* @throws Exception
*/
public static void outputOptr(String optr,
Stack optrStack,
List  rpnList)
throws Exception{
String preOptr;

if(optr.equals("(")){//处理左括号
optrStack.push(optr);
return;
}

if(optr.equals(")")){//处理右括号
while(!optrStack.isEmpty()){
preOptr=optrStack.pop();
if(!preOptr.equals("(")){
rpnList.add(preOptr);
}else{
break;
}
}

if(optrStack.isEmpty()){
throw new Exception("括号未闭合!");
}

return;
}

/*按优先级处理其他运算符,若当前运算符优先级较高
* 直接入栈,否则将栈中运算符出战直至栈顶运算符
* 低于当前运算符
*/
preOptr=optrStack.lastElement();
if(optrCmp(optr,preOptr)<0){
optrStack.push(optr);
}else{
while(!preOptr.equals("(")
&&!optrStack.isEmpty()
&&optrCmp(optr,preOptr)>=0){

preOptr=optrStack.pop();
if(!preOptr.equals("^")){
rpnList.add(preOptr);
}
}
optrStack.push(optr);
}
}

/**
* 运算符优先级比较函数,optr1优先级大于optr2返回小于0值,
* 优先级相等返回0,optr1小于optr2返回大于0值.
* @param optr1
* @param optr2
* @return
*/
public static int optrCmp(String optr1,String optr2){
int order1=optrOrder.get(optr1);
int order2=optrOrder.get(optr2);
return order1-order2;
}

/**
* 根据运算符对数据栈中的内容进行操作.
* @param optr
* @param numStack
*/
public static void  doCalcByOptr(String optr,
Stack numStack){
double n1,n2;
n2=numStack.pop();
n1=numStack.pop();

if(optr.equals("+")){
numStack.push(n1+n2);
}else if(optr.equals("-")){
numStack.push(n1-n2);
}else if(optr.equals("*")){
numStack.push(n1*n2);
}else if(optr.equals("/")){
numStack.push(n1/n2);
}else if(optr.equals("%")){
numStack.push(n1%n2);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: