本文代码未使用栈
问题描述
输入一个表达式,表达式可以包括‘+’,‘-’,‘*’,‘/’,‘%’运算,可以出现整数及小数,可以出现“()”,但要求输入格式合法。
总体思路
当输入的表达式(下称s)中存在“()”时,对“()”内的表达式进行运算,并在s中将该“()”及其之中的表达式替换为运算结果;
直至s中无“()”,对s进行运算,输出结果。
运算思路
现在我们只需要考虑如何计算出一个没有“()”的表达式即可。
首先,明确:‘*’,‘/’,‘%’的运算优先级相同,且高于‘+’,‘-’,而‘+’,‘-’的运算优先级亦相同。
故我们可以将表达式运算拆为两部分,即乘除余的运算与加减的运算,现在,我们只需处理相同优先级的运算符,表达式的运算只需将二者按次序结合即可。(由于本算法思路为用结果替代指定的表达式部分,故二者不会相互干扰)
由于这两部分运算思路相仿,整体上的不同基本就是运算符的差异,故下面描述的算法适用于任一部分。
算法描述
1.确定运算符位置
检测表达式,记录首先出现的运算符。
2.确定运算数
以记录的运算符的位置分别向前向后检测,直到检测到运算符则停止,这两段字符串便是运算数(一个很重要的干扰项便是负数的存在,但由于要求输入的表达式必须合法,故在检测到‘-’的时候,只需检验下一个字符是不是运算符,若是或者没有下一个字符,则该运算数为负数,将该‘-’加入运算数的字段;若不是,则正常操作即可)。
3.确定运算数类型
检测两个运算数字段中是否有‘.’,若有,则设定结果为小数;否则,为整数。
4.检测与替换
检测表达式是否还含有该优先级的运算符,但要注意(没错,负数又来作妖了),若检测发现只有一个运算符,且那个运算符是‘-’并在第一个位置,这说明没有运算符了,那玩意(‘-’)是负数的东西,不用管。
在排除上述情况后,若有运算符,则继续对它进行运算;否则,用运算结果替换表达式(注意,若表达式在括号内部顺便把括号删了)。
代码
import java.util.Scanner;
public class java_fo {
public static String multde(String in)
//乘除余运算
{
int s1=in.indexOf('*');
int s2=in.indexOf('/');
int s3=in.indexOf('%');
if(s1==-1&&s2==-1)
s1=s3;
else if(s1==-1&&s3==-1)
s1=s2;
else if(s2==-1&&s3==-1)
;
else
{
if(s1==-1)
s1=in.length();
if(s2==-1)
s2=in.length();
if(s3==-1)
s3=in.length();
s2=Math.min(s2, s3);
s1=Math.min(s1, s2);
}
//确定运算符位置,若无运算符则为-1
int t1=s1;
while((in.charAt(t1-1)>='0'&&in.charAt(t1-1)<='9')||in.charAt(t1-1)=='.')
{
t1--;
if(t1<1)
break;
}
int t2=s1;
if(t1==0);
else if(t1==1)
t1--;
else if(in.charAt(t1-1)=='-')
if(!(in.charAt(t1-2)>='0'&&in.charAt(t1-2)<='9'))
t1--;
if(!((in.charAt(t2+1)>='0'&&in.charAt(t2+1)<='9')||in.charAt(t2+1)=='.'))
t2++;
while((in.charAt(t2+1)>='0'&&in.charAt(t2+1)<='9')||in.charAt(t2+1)=='.')
{
t2++;
if(t2>in.length()-2)
break;
}
//获取运算数起/末位置
String a1=in.substring(t1, s1);
String a2=in.substring(s1+1, t2+1);
int fla1,fla2;
fla1=fla2=0;
if(a1.indexOf('.')==-1)
fla1=1;
if(a2.indexOf('.')==-1)
fla2=1;
//检测两数是否为小数
double m,n;
int m1,n1;
double m2,n2;
if(fla1==0)
{
m=Double.parseDouble(a1);
m2=m;
}
else
{
m1=Integer.valueOf(a1);
m2=m1;
}
if(fla2==0)
{
n=Double.parseDouble(a2);
n2=n;
}
else
{
n1=Integer.valueOf(a2);
n2=n1;
}
//将两数转为对应的数字类型
double res;
if(in.charAt(s1)=='*')
res=m2*n2;
else if(in.charAt(s1)=='/')
res=m2/n2;
else
res=m2%n2;
//据运算符进行运算,得到结果
String resu;
if(fla1==1&&fla2==1)
resu=String.valueOf((int)res);
else
resu=String.valueOf((float)res);
//将结果转为对应类型,并转为字符串
StringBuilder ini=new StringBuilder(in);
ini.replace(t1,t2+1,resu);
in=ini.toString();
return in;
//替换,返回替换后的表达式
}
public static String plusde(String in)
//加减运算,思路与上同
{
int s1=in.indexOf('+');
int s2=in.indexOf('-');
if(s1==-1&&s2==-1)
return in;
else if(s1==-1&&s2==0)
s1=in.lastIndexOf('-');
else if(s1==-1)
s1=s2;
else if(s1!=-1&&s2==0)
;
else if(s1!=-1&&s2!=-1)
s1=Math.min(s1, s2);
int t1=s1;
while((in.charAt(t1-1)>='0'&&in.charAt(t1-1)<='9')||in.charAt(t1-1)=='.')
{
t1--;
if(t1<1)
break;
}
int t2=s1;
if(t1==0);
else if(t1==1)
t1--;
else if(in.charAt(t1-1)=='-')
if(!(in.charAt(t1-2)>='0'&&in.charAt(t1-2)<='9'))
t1--;
if(!((in.charAt(t2+1)>='0'&&in.charAt(t2+1)<='9')||in.charAt(t2+1)=='.'))
t2++;
while((in.charAt(t2+1)>='0'&&in.charAt(t2+1)<='9')||in.charAt(t2+1)=='.')
{
t2++;
if(t2>in.length()-2)
break;
}
String a1=in.substring(t1, s1);
String a2=in.substring(s1+1, t2+1);
int fla1,fla2;
fla1=fla2=0;
if(a1.indexOf('.')==-1)
fla1=1;
if(a2.indexOf('.')==-1)
fla2=1;
double m,n;
int m1,n1;
double m2,n2;
if(fla1==0)
{
m=Double.parseDouble(a1);
m2=m;
}
else
{
m1=Integer.valueOf(a1);
m2=m1;
}
if(fla2==0)
{
n=Double.parseDouble(a2);
n2=n;
}
else
{
n1=Integer.valueOf(a2);
n2=n1;
}
double res;
if(in.charAt(s1)=='+')
res=m2+n2;
else
res=m2-n2;
String resu;
if(fla1==1&&fla2==1)
resu=String.valueOf((int)res);
else
resu=String.valueOf((float)res);
StringBuilder ini=new StringBuilder(in);
ini.replace(t1,t2+1,resu);
in=ini.toString();
return in;
}
public static String work(String in)
//统筹两种运算
{
while(in.indexOf('*')!=-1||in.indexOf('/')!=-1||in.indexOf('%')!=-1)
in=multde(in);
//只要存在*,/,%便继续运算
while(in.indexOf('+')!=-1||in.indexOf('-')!=-1)
{
if(in.indexOf('-')==0&&in.indexOf('-',1)==-1)
if(in.indexOf('+')==-1)
break;
in=plusde(in);
}
//检测不是只剩一个负数,且有运算符,则继续运算
return in;
}
public static void main(String[] arg)
{
Scanner in=new Scanner(System.in);
String input=in.nextLine();
input=input.replace(" ","");
while(input.indexOf(')')!=-1)
//检测是否有'('
{
int end=input.indexOf(')');
int sta=input.lastIndexOf('(',end);
String cir=input.substring(sta+1,end);
String cirt=input.substring(sta,end+1);
String cirr=work(cir);
input=input.replace(cirt,work(cir));
//替换,消括号
}
System.out.println(work(input));
}
}
测试
输入:
(2+4/2*2-1)*2-6
输出:
4
输入:
5*11%3
输出:
1