1 import java.util.Scanner; 2 import java.math.*; 3 public class jisuanqi { 4 public static void main(String[] args) { 5 jisuanqi ca=new jisuanqi(); 6 System.out.println("请在下面输入计算内容:\n按#退出"); 7 ca.shuru(); 8 System.out.println("\n\n\n---------------------------------谢谢使用!-------------------------------"); 9 } 10 void shuru(){ //输入控制 11 String shi="",temp; 12 Scanner ss=new Scanner(System.in); 13 while(true){ 14 shi=""; 15 while(true){ 16 temp=ss.next(); 17 shi+=temp; 18 if(temp.indexOf(‘#‘)!=-1 )return; 19 20 if(temp.indexOf(‘=‘)!=-1){ //有等号 21 jiancha(shi); 22 System.out.println("------------------------------------------------------------------------\n请在下面输入计算内容:\n按#退出"); 23 break; 24 } 25 } 26 } 27 } 28 29 void jiancha(String s){ //表达式处理及检查 30 31 s=s.replaceAll(" | ", ""); //移除空格、tab符 32 33 if(s.charAt(s.length()-1)!= ‘=‘){ //等号位置不正确 34 System.out.println("表达式不正确,等号后面有多余表达项"); 35 return; 36 } 37 38 if(s.length()!= //保证只有一个= 39 (s.replaceAll("=","")).length()+1){ 40 System.out.println("表达式不正确,含多个等号"); 41 return; 42 } 43 s=s.replaceAll("=", ""); //此处移除等号,形成表达式 44 45 char a; 46 for(int i=0;i<s.length();i++){ 47 a=s.charAt(i); 48 49 if( (a>‘9‘|a<‘0‘)&&a!=‘+‘&&a!=‘-‘ //表达式之外意外字符 50 &&a!=‘*‘&&a!=‘/‘&&a!=‘(‘&&a!=‘)‘ 51 &&a!=‘.‘){ 52 System.out.println("表达式不正确,含意外字符 \""+String.valueOf(a)+"\"!!!"); 53 return; 54 } 55 } 56 57 if( (s.replaceAll("\\)", "").length()) != //保证括号有效对数 ,注意转义字符 58 (s.replaceAll("\\(", "").length()) ){ 59 System.out.println("表达式不正确,括号不是有效对数!!!"); 60 return; 61 } 62 63 if(s.replaceAll(" | ", "").length()==0){ 64 System.out.println("没有输入表达式"); 65 return; 66 } 67 String jg=cixu(s); 68 if(jg.equals("#")) return; 69 if(jg.charAt(0)==‘+‘){ 70 jg+=‘ ‘; 71 jg=jg.substring(1, jg.length()-1); 72 } 73 System.out.println("结果为: "+jg); 74 75 } 76 77 String cixu(String s){ //表达式计算优先级处理 78 int d1,d2,k1=-1,k2=-1; 79 String subs; 80 boolean iskuo=false; 81 82 while(true){ 83 if( (k2=s.indexOf(‘)‘) )!=-1 ){ //定位后括号位置 84 k1=k2; 85 while(k1>=0&s.charAt(k1)!=‘(‘ ){ 86 k1--; 87 if(k1<0)break; 88 } 89 //定位前括号位置 90 if(k1==-1){ // )(的情况 91 System.out.println("括号被没有被匹配"); // )括号被没有匹配 92 return "#"; 93 } 94 95 96 if(k1+1==k2){ //空括号情况 97 System.out.println("括号内不能为空"); 98 return "#"; 99 } 100 if( k1+2==k2&&( //括号内只有操作符情况 101 s.charAt(k1+1)==‘*‘| 102 s.charAt(k1+1)==‘/‘| 103 s.charAt(k1+1)==‘+‘| 104 s.charAt(k1+1)==‘-‘| 105 s.charAt(k1+1)==‘.‘ 106 ) 107 ){ 108 System.out.println("括号内不能没有数字"); 109 return "#"; 110 } 111 subs=s.substring(k1+1, k2); 112 if( subs.replaceAll("[+]|-|[*]|/", "").length()==subs.length()){ 113 if(k1==0&k2==s.length()-1) s=subs; 114 else if(k1==0)s=subs+s.substring(k2+1,s.length()); 115 else if(k2==s.length()-1)s=s.substring(0, k1)+subs; 116 else s=s.substring(0, k1)+subs+s.substring(k2+1, s.length()); 117 continue; 118 } 119 iskuo=true; 120 } 121 else { 122 subs=s; 123 //仅为某一无符数字时 124 if( subs.replaceAll("[+]|-|[*]|/", "").length()==subs.length())return s; 125 iskuo=false; 126 } 127 128 if(subs.indexOf(‘*‘)==0|subs.indexOf(‘/‘)==0){ //首部异常检查 129 System.out.println("不能出现像 *或 /开头的数字 这样的表达"); 130 return "#"; 131 } 132 if( ( subs.charAt(subs.length()-1)<‘0‘| //尾部异常检查 133 subs.charAt(subs.length()-1)>‘9‘ )&& 134 subs.charAt(subs.length()-1)!=‘.‘ 135 ){ 136 System.out.println("不能出现像 表达式 操作符 这样以操作符结尾的的表达"); 137 return "#"; 138 } 139 //错误操作符组合检查 140 if( subs.replaceAll("[+][*]", "").length()!=subs.length() | 141 subs.replaceAll("[-][*]", "").length()!=subs.length() | 142 subs.replaceAll("[*][*]", "").length()!=subs.length() | 143 subs.replaceAll("[/][*]", "").length()!=subs.length() | 144 subs.replaceAll("[+][/]", "").length()!=subs.length() | 145 subs.replaceAll("[-][/]", "").length()!=subs.length() | 146 subs.replaceAll("[*][/]", "").length()!=subs.length() | 147 subs.replaceAll("[/][/]", "").length()!=subs.length()) 148 { 149 System.out.println("不能出现像**、+*、//这样的表达"); 150 return "#"; 151 } 152 //表达式为某一数值时不参与调用函数jisuan() 153 if(subs.replaceAll("[+]|-|[*]|/","").length()+1==subs.length()&& 154 (subs.charAt(0)==‘+‘|subs.charAt(0)==‘-‘)) 155 { 156 if(iskuo){ 157 if(k1==0&k2==s.length()-1)s=subs; 158 else if(k1==0)s=subs+s.substring(k2+1); 159 else if(k2==s.length()-1)s=s.substring(0, k1)+subs; 160 else s=s.substring(0, k1)+subs+s.substring(k2+1); 161 } 162 else s=subs; 163 //判断总表达式是否仅仅为某一数值 164 if(s.replaceAll("[+]|-", "").length()+1==s.length() 165 && (s.charAt(0)==‘+‘| 166 s.charAt(0)==‘-‘) 167 )break; 168 else continue; 169 } 170 if((subs.charAt(0)<=‘9‘&subs.charAt(0)>=‘0‘)|subs.charAt(0)==‘.‘) 171 subs=‘+‘+subs; //式子首部进行处理 172 173 d1=1;//定位第一个操作数最后一位,第一次取1 174 while(true){ //对表达式的遍历处理 175 while( (subs.charAt(d1)>=‘0‘& //定位第一个操作数最后一位 176 subs.charAt(d1)<=‘9‘)| 177 subs.charAt(d1)==‘.‘) 178 { 179 if(subs.length()-1==d1)break; 180 else if( (subs.charAt(d1+1)<‘0‘| 181 subs.charAt(d1+1)>‘9‘)& 182 subs.charAt(d1+1)!=‘.‘ )break; 183 else d1++; 184 } 185 186 d2=d1+1;//定位第二个操作符首位 187 int i; 188 for(i=d2;i<subs.length();i++){ 189 if((subs.charAt(i)<=‘9‘&subs.charAt(i)>=‘0‘)|subs.charAt(i)==‘.‘)break; 190 } 191 d2=i; 192 193 if(d2-d1>3){ 194 System.out.println("在两数之间可能出现多个乘除或三个以上加减"); 195 return "#"; 196 } 197 198 //标明数值正负 199 if((subs.charAt(d1+2)<=‘9‘&&subs.charAt(d1+2)>=‘0‘) 200 |subs.charAt(d1+2)==‘.‘){ 201 subs=insretplus(subs,d1+2); 202 d2++; 203 } 204 205 for(i=d2;i<subs.length();i++){ 206 if((subs.charAt(i)>‘9‘|subs.charAt(i)<‘0‘)&&subs.charAt(i)!=‘.‘)break; 207 } 208 if( i>=subs.length()-1)break; 209 d1=d2; 210 } 211 //以上保证了操作符与操作数的正确连接· 212 subs=jisuan(subs); 213 if(subs==""){ 214 System.out.println("不能出现除0的情况"); 215 return "#"; //出现除0的情况 216 } 217 218 if(iskuo){ 219 if(k1==0&k2==s.length()-1)s=subs; 220 else if(k1==0)s=subs+s.substring(k2+1); 221 else if(k2==s.length()-1){ 222 if(s.charAt(k1-1)==‘-‘&& //考虑到去括号多出正负表示符 223 (s.charAt(k1-2)==‘+‘| 224 s.charAt(k1-2)==‘-‘| 225 s.charAt(k1-2)==‘*‘| 226 s.charAt(k1-2)==‘/‘) 227 ){ 228 if(subs.charAt(0)==‘+‘){ 229 subs+=‘ ‘; 230 s=s.substring(0, k1)+subs.substring(1, subs.length()-1); 231 } 232 else { 233 subs+=‘ ‘; //防止出错 234 s=s.substring(0, k1-1)+‘+‘+subs.substring(1, subs.length()-1); 235 } 236 } 237 else if( s.charAt(k1-1)==‘+‘&& //考虑到去括号多出正负表示符 238 (s.charAt(k1-2)==‘+‘| 239 s.charAt(k1-2)==‘-‘| 240 s.charAt(k1-2)==‘*‘| 241 s.charAt(k1-2)==‘/‘) 242 )s=s.substring(0, k1-1)+subs; 243 else s=s.substring(0, k1)+subs; 244 } 245 else { 246 if(s.charAt(k1-1)==‘-‘&& 247 (s.charAt(k1-2)==‘+‘| 248 s.charAt(k1-2)==‘-‘| 249 s.charAt(k1-2)==‘*‘| 250 s.charAt(k1-2)==‘/‘) 251 ){ 252 if(subs.charAt(0)==‘+‘){ 253 subs+=‘ ‘; 254 s=s.substring(0, k1)+subs.substring(1, subs.length()-1)+s.substring(k2+1,s.length()-1 ); 255 } 256 else { 257 subs+=‘ ‘; //防止出错 258 s=s.substring(0, k1-1)+‘+‘+subs.substring(1, subs.length()-1)+s.substring(k2+1,s.length()-1 ); 259 } 260 } 261 else if( s.charAt(k1-1)==‘+‘&& //考虑到去括号多出正负表示符 262 (s.charAt(k1-2)==‘+‘| 263 s.charAt(k1-2)==‘-‘| 264 s.charAt(k1-2)==‘*‘| 265 s.charAt(k1-2)==‘/‘) 266 )s=s.substring(0, k1-1)+subs+s.substring(k2+1,s.length() ); 267 else s=s.substring(0, k1)+subs+s.substring(k2+1,s.length() ); 268 } 269 } 270 else s=subs; 271 if(s.replaceAll("[+|-]", "").length()+1==s.length() 272 &&(s.charAt(0)==‘+‘|s.charAt(0)==‘-‘) )break; 273 } 274 return s; 275 } 276 277 String jisuan(String s){ //计算标准表达式 278 int you,p,b; 279 double pp,bb,jg; 280 String s1,s2,s3; 281 282 while((you=s.indexOf(‘*‘))!=-1){//乘优先级 283 p=you; //获取前后两操作数在字符串的定位 284 b=you+2; 285 //定位前后操作数的位置 286 while(s.charAt(p)!=‘+‘&s.charAt(p)!=‘-‘)p--; 287 while(‘0‘<=s.charAt(b)&‘9‘>=s.charAt(b)|s.charAt(b)==‘.‘){ 288 if(b==s.length()-1)break; //达到最后一位时,注意不要超限 289 if(s.charAt(b+1)!=‘.‘&(s.charAt(b+1)<‘0‘|s.charAt(b+1)>‘9‘)) break; 290 b++; 291 } 292 293 s1=s.substring(p,you); 294 s2=s.substring(you+1,b+1); 295 296 pp=Double.parseDouble(s1); //第一个操作数 297 bb=Double.parseDouble(s2); //第二个操作数 298 jg=pp*bb; 299 s3=s1+"*"+s2; 300 s3=s3.replaceAll("[+]", "[+]"); //此处用法特别注意,正则表达式用法 301 s3=s3.replaceAll("[*]", "[*]"); 302 if(jg<0)s=s.replaceFirst(s3,String.valueOf(jg)); 303 else s=s.replaceFirst(s3, "+"+String.valueOf(jg)); //正负号标准化 304 } 305 306 while((you=s.indexOf(‘/‘))!=-1){//乘优先级 307 p=you; 308 b=you+2; 309 310 while(s.charAt(p)!=‘+‘&s.charAt(p)!=‘-‘)p--; 311 while(‘0‘<=s.charAt(b)&‘9‘>=s.charAt(b)|s.charAt(b)==‘.‘){ 312 if(b==s.length()-1)break; 313 if(s.charAt(b+1)!=‘.‘&(s.charAt(b+1)<‘0‘|s.charAt(b+1)>‘9‘)) break; 314 b++; 315 } 316 317 s1=s.substring(p,you); 318 s2=s.substring(you+1,b+1); 319 320 pp=Double.parseDouble(s1); 321 bb=Double.parseDouble(s2); 322 if(bb==0) return ""; 323 324 jg=pp/bb; 325 s3=s1+"/"+s2; 326 s3=s3.replaceAll("[+]", "[+]"); 327 s3=s3.replaceAll("[/]", "[/]"); 328 if(jg<0)s=s.replaceFirst(s3,String.valueOf(jg)); 329 else s=s.replaceFirst(s3, "+"+String.valueOf(jg)); 330 } 331 332 //加减运算 333 while(s.length()>s.replaceAll("[+]|[-]", "").length()+1){ 334 p=0; 335 you=1; 336 while(‘0‘<=s.charAt(you)&‘9‘>=s.charAt(you)|s.charAt(you)==‘.‘){ 337 if(you==s.length()-1)break; 338 if(s.charAt(you+1)!=‘.‘&(s.charAt(you+1)<‘0‘|s.charAt(you+1)>‘9‘)) break; 339 you++; 340 } 341 you+=1; //注意一第二个操作数提取的不同点 342 b=you+2; 343 while(‘0‘<=s.charAt(b)&‘9‘>=s.charAt(b)|s.charAt(b)==‘.‘){ 344 if(b==s.length()-1)break; 345 if(s.charAt(b+1)!=‘.‘&(s.charAt(b+1)<‘0‘|s.charAt(b+1)>‘9‘)) break; 346 b++; 347 } 348 s1=s.substring(p,you); 349 s2=s.substring(you+1,b+1); 350 351 352 pp=Double.parseDouble(s1); 353 bb=Double.parseDouble(s2); 354 355 if(s.charAt(you)==‘+‘){ 356 jg=pp+bb; 357 s3=s1+"+"+s2; 358 } 359 else { 360 jg=pp-bb; 361 s3=s1+"-"+s2; 362 } 363 s3=s3.replaceAll("[+]", "[+]"); 364 if(jg<0)s=s.replaceFirst(s3,String.valueOf(jg)); 365 else s=s.replaceFirst(s3, "+"+String.valueOf(jg)); 366 } 367 if(s.length()>10)s=s.substring(0, 11); 368 369 return s; 370 } 371 372 String insretplus(String s,int stratid){ //在指定位置前插入‘+’ 373 String s1,s2; 374 s1=s.substring(0, stratid); 375 s2=s.substring(stratid, s.length()); 376 return s1+‘+‘+s2; 377 } 378 }
时间: 2024-12-15 19:19:08