本文代碼未使用棧
問題描述
輸入一個表達式,表達式可以包括‘+’,‘-’,‘*’,‘/’,‘%’運算,可以出現整數及小數,可以出現“()”,但要求輸入格式合法。
總體思路
當輸入的表達式(下稱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