########################################just use for practice########################################!/usr/bin/perl#use warning#use diagnostics;#use diagnositc#use warnings;#use warning#use strict;#use strict#This means you MUST always use#-------------MY---------------#before you new any variants#use strict;################################################################用Perl實現的四則運算,可以處理括弧。但是沒有考慮太多異常系。#比如括弧數量不匹配,或者輸入了非括弧,非加減乘除好等。##基本思路為有括弧,則進行遞迴,找到第一個最小的括弧,遞迴之。#計算出結果後,替換整個括弧內容。比如(1+3),整體替換為數字4。#由於每次遞迴到最後到最後,將會是只有左右括弧,中間是不包含#括弧的算式。此時進行普通運算。#從頭開始匹配,如果找到數字,則壓入數字棧。找到符號,則壓入#符號棧。在找到*/號的時候,立馬取出前一個數字,與當前數字計算,#然後壓入數字棧。在照完第一遍以後,棧中只剩下數字和加減號。#依次取出一個符號,和兩個數字計算,知道棧中為空白。#最後的結果即為最終的結果。###############################################################$in_expression="(1+1)*(3*(2+2))"; #你的運算式寫在這裡。這個也可以改為手動輸入print "Your expression is:\n$in_expression\n\n";$ans=&cal($in_expression);#調用函數,參數為第二個數sub cal(){########################################################################################################my $ret=0; my $para=$_[0];#擷取傳入的參數值while($para=~/\(.*?\)/)#只要參數還有括弧(),就進行處理,要麼去掉開頭括弧,要麼進行遞迴{if($para=~/^\([^\(]*?\)$/)#在以前括弧 "(" 開頭,後括弧 ")" 結尾, 而且中間全是非前括弧 "(" 的情況下, 去頭尾{$para=~s/^\(//;#去掉前括弧 ($para=~s/\)$//;#去掉後括弧 )}if($para=~/\([^\(]*?\)/)#將第一組有括弧的字串進行遞迴{ $ret=&cal($&);$para=~s/\([^\(]+?\)/$ret/;#算出了第一個括弧內的值,把它用來替換第一個括弧的整體內容(包括括弧)#用非貪婪的來限定為第一個括弧$cnt++;print "$cnt. $para\n";}}#以上為對括弧的運算,有括弧的情況下,需要去掉括弧或者遞迴#########################################################################################################以下為沒有括弧的情況下,進行的四則運算 my @my_num=();#用來儲存數字 my @my_ope=();#用來儲存運算子 while($para ne '')#while not complete { if($para=~s/^(\d+)//)#find the numbers { push @my_num,$1;#store the numbers } if($para=~s/(\D+?)//)#find the operators {#------------------------------------------------------------------#以下優先度較高的乘除運算,立馬取出前一個數字,與當前數字進行計算 if($1 eq '*') { if($para=~s/^(\d+)//)#if there is a number after '*' { $tmp_L=pop @my_num;$tmp_R=$1; $tmp=$tmp_L*$tmp_R; push @my_num,$tmp;#push the caled number to @my_num } } elsif($1 eq '/') { if($para=~s/^(\d+)//)#if there is a number after '/'{ $tmp_L=pop @my_num;$tmp_R=$1; $tmp=$tmp_L/$tmp_R; push @my_num,$tmp;#push the caled number to @my_num } }#以上優先度較高的乘除運算,立馬取出前一個數字,與當前數字進行計算#------------------------------------------------------------------ else#加減符號,先儲存起來 { push @my_ope,$1;#store the operators } } }#########################################################################################################乘除符號已經處理完畢,此時只剩下加減符號,從後向前進行處理也是可以的。(因為加法結合律) while(@my_ope!=0) { if(pop @my_ope eq '+')#感覺這裡基本不需要注釋了 { $tmp_R=pop @my_num; $tmp_L=pop @my_num; $tmp=$tmp_L+$tmp_R; push @my_num,$tmp; } elsif(pop @my_ope eq '-') { $tmp_R=pop @my_num; $tmp_L=pop @my_num; $tmp=$tmp_L-$tmp_R; push @my_num,$tmp; } } return pop @my_num;}print "\nThe result is: $ans\n";######################################################################################################################################################################################print "\n\n\n";print "Press any key to exit...";<>;#Stop to show the result