计算器思路;
单位数计算器
package com.marden.demo3;
//单位数表达式
public class Calculator {
//判断是否为操作符
public static boolean isOper(char value){
return value=='+'||value=='-'||value=='*'||value=='/';
}
//判断优先级,优先级使用数字表示,数字越大,则优先级越高
public static int priority(int i){
if(i=='*'|| i=='/'){
return 1;
}else if(i=='+'|| i=='-'){
return 0;
}else{
return -1;
}
}
//计算方法
public static int cal(int num1,int num2,int oper){
int temp = 0;
switch (oper) {
case '+':
temp= num1+num2;
break;
case '-':
temp= num2-num1;
break;
case '*':
temp= num1*num2;
break;
case '/':
temp= num2/num1;
break;
default:
break;
}
return temp;
}
public static void main(String[] args) {
String expression="3*6/2-1+3*3";
//创建两个栈,完成表达式的计算
ArrayStack numStack=new ArrayStack(10); //数字栈
ArrayStack operStack=new ArrayStack(10); //符号栈
//定义需要的相关变量
int index=0; //扫描的下标志
int num1=0; //数字栈中的第一个出栈元素
int num2=0; //数字栈中的第二个出栈元素
int oper=0; //操作符
int rs=0; //结果
while(true){
//将每次扫描得到的char保存到temp中
char temp=expression.substring(index, index+1).charAt(0);
//判断temp是什么,然后做相应的处理
//判断字符是否为数字,如果是数字则直接压入数字栈
if(!isOper(temp)){
numStack.push(temp-48); //次数获取到的是字符,根据ASCII表,转成对应的数字
}else{
//如果字符为符号,则分两种情况
//1.如果符号栈为空,则直接入栈
if(operStack.isEmpty()){
operStack.push(temp);
}else{
//2.如果符号栈不为空,则分两种情况
//2.1 如果当前符号的优先级比符号栈中栈顶的符号优先级高,则直接入栈
if(priority(temp)>priority(operStack.topElement())){
operStack.push(temp);
}else{
//2.2 如果当前符号的优先级比符号栈中栈顶的符号优先级低或者相同,则从数字栈中出栈两个数字,从符号栈中出栈一个符号进行计算,并将计算结果压入数字栈
num1=numStack.pop();
num2=numStack.pop();
oper=operStack.pop();
rs=cal(num1, num2, oper);
numStack.push(rs);
//符号直接入栈
operStack.push(temp);
}
}
}
index++;
if(index==expression.length()){
break;
}
}
while(!operStack.isEmpty()){
num1=numStack.pop();
num2=numStack.pop();
oper=operStack.pop();
rs=cal(num1, num2, oper);
numStack.push(rs);
}
int sqc=numStack.pop();
System.out.println(expression+"="+sqc);
}
}
class ArrayStack{
private int maxSize;
private int [] stack;
private int top;
public ArrayStack(int maxSize){
this.maxSize=maxSize;
stack=new int [this.maxSize];
top=-1;
}
//查看栈顶元素的内容
public int topElement(){
return stack[top];
}
//判断栈满
public boolean isFull(){
return top==maxSize-1;
}
//判断栈空
public boolean isEmpty(){
return top==-1;
}
//入栈
public void push(int value){
//首先判断是否栈满,若栈满则无法入栈
if(isFull()){
System.out.println("栈满,无法入栈");
}else{
top++;
stack[top]=value;
}
}
//出栈
public int pop(){
//首先判断是否栈空,若栈空则无法出栈
if(isEmpty()){
System.out.println("栈空,无法出栈");
return -999;
}else{
int temp=stack[top];
top--;
return temp;
}
}
public void show(){
//首先判断是否栈空,若栈空则无法显示
if(isEmpty()){
System.out.println("栈空,无法显示数据");
}else{
for(int i=top;i>=0;i--){
System.out.println(stack[i]);
}
}
}
}
多位数计算器
package com.marden.demo3;
/*
* 分析思路:
* 1.当处理多位数的时,不能发现是一个数就立即入栈,因为它可能是多位数
* 2.在处理数据时,需要向expression的表达式的index后再看一位,如果是数就进行扫描,如果是符号则入栈
* 3.因此,我们需要定义一个变量,用于拼接
*/
//多位数表达式
public class Calculator1 {
public static boolean isOper(char value){
return value=='+'||value=='-'||value=='*'||value=='/';
}
public static int priority(int i){
if(i=='*'|| i=='/'){
return 1;
}else if(i=='+'|| i=='-'){
return 0;
}else{
return -1;
}
}
public static int cal(int num1,int num2,int oper){
int temp = 0;
switch (oper) {
case '+':
temp= num1+num2;
break;
case '-':
temp= num2-num1;
break;
case '*':
temp= num1*num2;
break;
case '/':
temp= num2/num1;
break;
default:
break;
}
return temp;
}
public static void main(String[] args) {
String expression="32+68-2*11";
ArrayStack numStack=new ArrayStack(10); //数字栈
ArrayStack operStack=new ArrayStack(10); //符号栈
int index=0;
int num1=0;
int num2=0;
int oper=0;
int rs=0;
char [] charTemp=expression.toCharArray();
while(true){
char temp=expression.substring(index, index+1).charAt(0);
//判断字符是否为数字,如果是数字则直接压入数字栈
if(!isOper(temp)){
//numStack.push(temp-48); //获取到的是字符,根据ASCII表,转成对应的数字
//如果是多位数,则需找到完整的数字,首先确定完整数字的边界
int end=charTemp.length-1;
for(int i=index;i<charTemp.length;i++){
if(isOper(charTemp[i])){
end=i-1;
break;
}
}
//将字符类型的数据转换成真实数字
int multiNum=0;
int count=0;
for(int i=end;i>=index;i--){
multiNum+=(charTemp[i]-48)*Math.pow(10, count); //根据ASCII表,将获取的字符转成对应的数字
count++;
}
//System.out.println(multiNum);
numStack.push(multiNum);
index=end;
}else{
//如果字符为符号,则分两种情况
//1.如果符号栈为空,则直接入栈
if(operStack.isEmpty()){
operStack.push(temp);
}else{
//2.如果符号栈不为空,则分两种情况
//2.1 如果当前符号的优先级比符号栈中栈顶的符号优先级高,则直接入栈
if(priority(temp)>priority(operStack.topElement())){
operStack.push(temp);
}else{
//2.2 如果当前符号的优先级比符号栈中栈顶的符号优先级低或者相同,则从数字栈中出栈两个数字,从符号栈中出栈一个符号进行计算,并将计算结果压入数字栈
num1=numStack.pop();
num2=numStack.pop();
oper=operStack.pop();
rs=cal(num1, num2, oper);
numStack.push(rs);
//符号直接入栈
operStack.push(temp);
}
}
}
index++;
if(index==expression.length()){
break;
}
}
while(!operStack.isEmpty()){
num1=numStack.pop();
num2=numStack.pop();
oper=operStack.pop();
rs=cal(num1, num2, oper);
numStack.push(rs);
}
int sqc=numStack.pop();
System.out.println(expression+"="+sqc);
}
}
class ArrayStack1{
private int maxSize;
private int [] stack;
private int top;
public ArrayStack1(int maxSize){
this.maxSize=maxSize;
stack=new int [this.maxSize];
top=-1;
}
//查看栈顶元素的内容
public int topElement(){
return stack[top];
}
//判断栈满
public boolean isFull(){
return top==maxSize-1;
}
//判断栈空
public boolean isEmpty(){
return top==-1;
}
//入栈
public void push(int value){
//首先判断是否栈满,若栈满则无法入栈
if(isFull()){
System.out.println("栈满,无法入栈");
}else{
top++;
stack[top]=value;
}
}
//出栈
public int pop(){
//首先判断是否栈空,若栈空则无法出栈
if(isEmpty()){
System.out.println("栈空,无法出栈");
return -999;
}else{
int temp=stack[top];
top--;
return temp;
}
}
public void show(){
//首先判断是否栈空,若栈空则无法显示
if(isEmpty()){
System.out.println("栈空,无法显示数据");
}else{
for(int i=top;i>=0;i--){
System.out.println(stack[i]);
}
}
}
}
带括号的多位数计算器:
package com.marden.demo3;
public class Calculator2 {
public static void main(String[] args) {
String expression = "2*(3+5)"; // 15//如何处理多位数的问题?
//创建两个栈,数栈,一个符号栈
ArrayStack2 numStack = new ArrayStack2(20);
ArrayStack2 operStack = new ArrayStack2(20);
//定义需要的相关变量
int index = 0;
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
char ch = ' '; //将每次扫描得到char保存到ch
String keepNum = ""; //用于拼接 多位数
//开始while循环的扫描expression
while(true) {
//依次得到expression 的每一个字符
ch = expression.substring(index, index+1).charAt(0);
//判断ch是什么,然后做相应的处理
if(isOper(ch)) {//如果是运算符
//判断当前的符号栈是否为空
if(!operStack.isEmpty()) {
//如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数,
//这里需要判断是否此时的栈顶是否为左括号,如果是左括号不进入此循环
//我们设定的左括号是优先级大于加减乘除,所以当发现下一个进栈的符号的优先级比此时的栈顶的左括号优先级小的时候,
//应该让符号直接进栈,不进行弹出左符号的运算(左括号弹出来运算是不行的)
if(priority(ch) <= priority(operStack.topElement()) & operStack.topElement()!=40) {
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = cal(num1, num2, oper);
//把运算的结果如数栈
numStack.push(res);
//然后将当前的操作符入符号栈
operStack.push(ch);
/**
* 进行右括号的判断。匹配左括号
* 当发现进入的是右括号时就优先进行括号内的计算
*/
} else if(ch==41){
//先让右括号进栈
operStack.push(ch);
if (ch==41) {
//再把右括号弹出
int oper1 = operStack.pop();
//弹出右括号后开始进行括号内运算
while(true) {
//右括号
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = cal(num1, num2, oper);
//把运算的结果如数栈
numStack.push(res);
//当运算到栈顶符号为左括号时候,就弹出栈顶元素左括号,结束循环
if(operStack.topElement()==40) {
int oper2 = operStack.pop();
break;
}
}
}
//如果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈.
}
else {
operStack.push(ch);
}
}else {
//如果为空直接入符号栈
operStack.push(ch);
}
} else { //如果是数,则直接入数栈
//分析思路
//1. 当处理多位数时,不能发现是一个数就立即入栈,因为他可能是多位数
//2. 在处理数,需要向expression的表达式的index 后再看一位,如果是数就进行扫描,如果是符号才入栈
//3. 因此我们需要定义一个变量 字符串,用于拼接
//处理多位数
keepNum += ch;
//如果ch已经是expression的最后一位,就直接入栈
if (index == expression.length() - 1) {
numStack.push(Integer.parseInt(keepNum));
}else{
//判断下一个字符是不是数字,如果是数字,就继续扫描,如果是运算符,则入栈
//注意是看后一位,不是index++
if (isOper(expression.substring(index+1,index+2).charAt(0))) {
//如果后一位是运算符,则入栈 keepNum = "1" 或者 "123"
numStack.push(Integer.parseInt(keepNum));
//重要的!!!!!!, keepNum清空
keepNum = "";
}
}
}
//让index + 1, 并判断是否扫描到expression最后.
index++;
if (index >= expression.length()) {
break;
}
}
//当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行.
while(true) {
//System.out.println(operStack.peek());
//如果符号栈为空,则计算到最后的结果, 数栈中只有一个数字【结果】
if(operStack.isEmpty()) {
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = cal(num1, num2, oper);
numStack.push(res);//入栈
}
//将数栈的最后数,pop出,就是结果
int res2 = numStack.pop();
System.out.printf("表达式 %s = %d", expression, res2);
}
//判断是否为操作符
public static boolean isOper(char value){
return value=='+'||value=='-'||value=='*'||value=='/' || value=='(' || value==')';
}
//判断优先级,优先级使用数字表示,数字越大,则优先级越高
public static int priority(int i){
if(i=='(' || i==')'){
return 2;
}
else if(i=='*'|| i=='/'){
return 1;
}else if(i=='+'|| i=='-'){
return 0;
}else{
return -1;
}
}
public static int cal(int num1,int num2,int oper){
int temp = 0;
switch (oper) {
case '+':
temp= num1+num2;
break;
case '-':
temp= num2-num1;
break;
case '*':
temp= num1*num2;
break;
case '/':
temp= num2/num1;
break;
default:
break;
}
return temp;
}
}
class ArrayStack2{
private int maxSize;
private int [] stack;
private int top;
public ArrayStack2(int maxSize){
this.maxSize=maxSize;
stack=new int [this.maxSize];
top=-1;
}
//查看栈顶元素的内容
public int topElement(){
return stack[top];
}
//判断栈满
public boolean isFull(){
return top==maxSize-1;
}
//判断栈空
public boolean isEmpty(){
return top==-1;
}
//入栈
public void push(int value){
//首先判断是否栈满,若栈满则无法入栈
if(isFull()){
System.out.println("栈满,无法入栈");
}else{
top++;
stack[top]=value;
}
}
//出栈
public int pop(){
//首先判断是否栈空,若栈空则无法出栈
if(isEmpty()){
System.out.println("栈空,无法出栈");
return -999;
}else{
int temp=stack[top];
top--;
return temp;
}
}
public void show(){
//首先判断是否栈空,若栈空则无法显示
if(isEmpty()){
System.out.println("栈空,无法显示数据");
}else{
for(int i=top;i>=0;i--){
System.out.println(stack[i]);
}
}
}
}
作业真题展示:
package com.bham.pij.assignments.calculator;
import java.util.regex.Pattern;
public class Calculator {
private float result;
public Calculator(){
}
public Calculator(String expression){
result=evaculator(expression);
}
public float evaculator(String expression){
//判断输入的字符串格式是否正确
String pattern1="^[0-9]+([.]{1}[0-9]+){0,1}$"; //正整数或者正小数的正则表达式
String pattern2="[-+*/]"; //四则运算的正则表达式
String [] arr=expression.split(" ");
float temp=0;
//若输入的字符串不合法
if(arr.length!=3 || Pattern.matches(pattern1, arr[0])&&Pattern.matches(pattern2, arr[1])&&Pattern.matches(pattern1, arr[2])==false
|| arr[1].equals("/")&&arr[2].equals("0")){
temp=Float.MIN_VALUE;
}else{ //若输入的字符串合法
float num1=Float.parseFloat(arr[0]);
float num2=Float.parseFloat(arr[2]);
if(arr[1].equals("+")){
temp=num1+num2;
}else if(arr[1].equals("-")){
temp=num1-num2;
}else if(arr[1].equals("*")){
temp=num1*num2;
}else{
temp=num1/num2;
}
}
return temp;
}
public float getCurrentValue(){
if(result==Float.MIN_VALUE){
return 0;
}else{
return result;
}
}
public static void main(String[] args) {
Calculator cal=new Calculator("3 + 4");
System.out.println(cal.getCurrentValue());
}
}