c語言用遞歸求逆波蘭,c語言實現逆波蘭式

本文目錄一覽:

C語言 逆波蘭表達式

這個問題可以分為3部分

1、輸入一個字元串,將其格式化的儲存在一個數組中,以方便的記錄表達式中數和各個符號的出現順序

約定在數組中記錄時,每個數或符號用兩個整數來記錄

第一個整數記錄該位是什麼東西,0表示是一個數,1表示是括弧,2表示反括弧,3、4、5、6分別表示乘除加減號

如果該位是一個數,那麼第二個整數記錄著個數的具體取值,否則記錄該位的符號的ASCII碼

比如字元串”(1-23)”會被轉化成二位數組 , , , , }

這個轉化過程每什麼技巧性,對原字元串各位順次判斷並處理即可

原先的字元串中可能出現一元運算符正號’+’和負號’-‘,為了處理方便,一律在其前面加個0,改寫成”0+…”或者”0-…”

另外為了之後轉化逆波蘭表達式方便,處理過程中會在轉化出的數組的首尾一律添加一對括弧

2、將之前所提到的格式數組轉化為逆波蘭表達式

約定依然用二位數組記錄一個逆波蘭表達式,並且格式與之前的數組相同,除了沒有括弧以外

比如逆波蘭表達式 1 2 – 35 +,會被記錄成{ , , , , }

轉化時,需要用一個棧

具體轉化操作如下:

順次處理格式數組的每一位,對其作判斷

如果該位是一個數或者是括弧'(‘,,將其入棧

如果該位是乘號’*’或者除號’/’,不斷進行出棧操作直到棧頂元素是個括弧'(‘或者加號’+’或者減號’-‘,然後將這個乘號或者除號入棧

如果該位是加號’+’或者減號’-‘,不斷進行出棧操作直到棧頂元素是個括弧'(‘,然後將這個加號或者減號入棧

如果該位是反括弧’)’,那麼不斷進行出棧操作直到有一個括弧'(‘出棧

在上述操作中,所有的出棧元素,除了括弧'(‘以外,都被順次添加到所要生成的逆波蘭表達式的末尾

這樣就轉化出了一條逆波蘭表達式

3、對逆波蘭表達式求值

求值時,也需要用到一個棧

求值步驟如下:

順次處理逆波蘭表達式的每一位,對其作判斷

如果該位是一個數,將這個數入棧

如果該位是一個運算符,那麼連續進行兩次出棧操作,可以得到棧頂的兩個元素,對這兩個元素用該位的運算符做運算,將所得的結果入棧

比如,如果當時棧頂元素是3,次棧頂的元素是2,運算符是減號’-‘,那麼連續兩次出棧得到3和2兩個元素,再將2-3的運算結果1入棧

注意有些運算符(減號和除號)不符合交換律,因此運算時必須是次棧頂元素在前、棧頂元素在後,順序不能反

當每一位都處理完了之後,只要輸入的是一個合法的逆波蘭表達式,必然棧中只剩下一個元素,這個元素就是逆波蘭表達式求值的結果

源代碼如下:

#include stdio.h

#include ctype.h

void transform(char *str,int a[][2],int *n)

//將輸入的字元串轉化為格式化的數組以記錄輸入的表達式,str為輸入的字元串,a為目標數組,n記錄數組a的大小

{

int i;

*n=1;

a[0][0]=1;

a[0][1]='(‘;//在表達式首添加一個括弧

for (i=0;str[i];)

{

if (isdigit(str[i]))

{

a[*n][0]=0;

a[*n][1]=0;

while (isdigit(str[i]))

{

a[*n][1]=a[*n][1]*10+str[i]-‘0’;

i++;

}

}

else

{

if (str[i]=='(‘) a[*n][0]=1;

else if (str[i]==’)’) a[*n][0]=2;

else if (str[i]==’*’) a[*n][0]=3;

else if (str[i]==’/’) a[*n][0]=4;

else if (str[i]==’+’ || str[i]==’-‘)

{

if (i==0 || (!isdigit(str[i-1]) str[i-1]!=’)’))

{

a[*n][0]=0;

a[*n][1]=0;

(*n)++;

}

if (str[i]==’+’) a[*n][0]=5;

else a[*n][0]=6;

}

a[*n][1]=str[i];

i++;

}

(*n)++;

}

a[*n][0]=2;

a[*n][1]=’)’;//在表達式尾添加一個反括弧

(*n)++;

}

void poland(int a[][2],int n,int p[][2],int *m)

//將格式化數組轉化為逆波蘭表達式,a為輸入的數組,n為其長度,p為輸出逆波蘭表達式的目標,m記錄逆波蘭表達式的長度

{

int i;

int stack[1000];//轉化所用的棧

int depth;//棧的深度

depth=0;

*m=0;

for (i=0;in;i++)

{

if (a[i][0]==0) stack[depth++]=i;

else if (a[i][0]==1) stack[depth++]=i;

else if (a[i][0]==2)

{

while (a[stack[depth-1]][0]!=1)

{

depth–;

p[*m][0]=a[stack[depth]][0];

p[*m][1]=a[stack[depth]][1];

(*m)++;

}

depth–;

}

else if (a[i][0]==3 || a[i][0]==4)

{

while (a[stack[depth-1]][0]==0 || a[stack[depth-1]][0]==3 || a[stack[depth-1]][0]==4)

{

depth–;

p[*m][0]=a[stack[depth]][0];

p[*m][1]=a[stack[depth]][1];

(*m)++;

}

stack[depth++]=i;

}

else if (a[i][0]==5 || a[i][0]==6)

{

while (a[stack[depth-1]][0]!=1)

{

depth–;

p[*m][0]=a[stack[depth]][0];

p[*m][1]=a[stack[depth]][1];

(*m)++;

}

stack[depth++]=i;

}

}

}

void print_poland(int p[][2],int m)

//列印逆波蘭表達式,p為逆波蘭表達式,m為表達式長度

{

int i;

for (i=0;im;i++)

{

if (p[i][0]==0) printf(“%d”,p[i][1]);

else printf(“%c”,p[i][1]);

}

putchar(‘\n’);

}

double evaluate(int p[][2],int m)

//對逆波蘭表達式求值,p為逆波蘭表達式,m為表達式長度

{

double stack[1000];//求值所用的棧

int depth;//棧的深度

int i;

depth=0;

for (i=0;im;i++)

{

if (p[i][0]==0) stack[depth++]=p[i][1];

else

{

double a,b;

b=stack[–depth];

a=stack[–depth];

if (p[i][0]==3) stack[depth++]=a*b;

else if (p[i][0]==4) stack[depth++]=a/b;

else if (p[i][0]==5) stack[depth++]=a+b;

else stack[depth++]=a-b;

}

}

return stack[0];

}

int a[1000][2];

int n;

int p[1000][2];

int m;

main()

{

transform(“5*(8-2)+9”,a,n);

poland(a,n,p,m);

print_poland(p,m);

printf(“The result of the expression is %lf\n”,evaluate(p,m));

return;

}

逆波蘭表達式求值 c++

這是典型的遞歸演算法(這是前綴表達式吧)即在函數中調用函數本身第一層遞歸時接受輸入字元(緩衝區10字元,第一個字元默認為0,防止不輸入)並讀取第一個字元。(總的來說就是為了讀取單個運算符號或者一串數字列)若讀取出為運算符號如’+’則在return時調用f()+f()這裡有兩次調用f(),每次調用f()時都需要請求你輸入字元。這兩次調用f()時,即進入了第二層遞歸。假定這裡你兩次輸入了’1′,’2’那麼對於第一層遞歸中的returnf()+f();其中第一個f()中返回了你的輸入1,第二個則返回2此時回到第一層,在f()+f()時就運算出結果3最終退出第一層遞歸,回到main()輸出前綴表達式的結果。如果更加複雜(輸入了很多運算符),同樣可以按照上面所說的這種思想來看。關於遞歸,一開始理解起來會有些困難,可以找些例子並且自己試驗。

C語言編寫逆波蘭計算器

#includestdio.h

#includestdbool.h

#includestdlib.h

#defineSTACK_SIZE 20

intmake_empty(void);

boolis_empty(void);

boolis_full(void);

voidpush(char );

voidpop(char );

voidstack_overflow(void);

voidstack_underflow(void);

charcontents[STACK_SIZE]= {0},top;

intmain(int argc, char *argv[])

{

char ch=’1′;

while(ch!=’q’){

make_empty();

printf(“Enter an RPNexpression:”);

do{

scanf(” %c”,ch);

if(ch=’1’ch=’9′)

push(ch);

else if(ch==’+’||ch==’-‘||ch==’*’||ch==’/’){

top–;pop(ch);

}

else if(ch==’=’){

if((top-1)==0)

pop(ch);

else

printf(“Nunber notused!”);

break;

}

else if(ch==’\n’);

else{

ch=’q’;break; /*其它情況置為退出標誌q*/

}

}

while(ch!=’\n’);

}

return 0;

}

intmake_empty(void){

/* return top=0;

}

boolis_empty(void){

return top==0;

}

boolis_full(void){

return top==STACK_SIZE;

}

voidpush(char ch){

if(is_full())

stack_overflow();

else

contents[top++]=ch-‘0’;

}

voidpop(char ch){

if(is_empty())

stack_underflow();

else

switch(ch){

case’+’:contents[top-1]+=contents[top];break;

case ‘-‘:contents[top-1]-=contents[top];break;

case’*’:contents[top-1]*=contents[top];break;

case’/’:contents[top-1]/=contents[top];break;

case ‘=’:printf(“Value ofexpression:%d\n”,(int)contents[0]);break;

}

}

voidstack_overflow(void){

printf(“Expression is toocomplex!”);

exit(EXIT_FAILURE);

}

voidstack_underflow(void){

printf(“Not enough operands inexpression!”);

exit(EXIT_FAILURE);

}

逆波蘭表達式(遞歸)形成棧

不是,cin只是用來讀取數據。

實際上這個程序巧妙地用了遞歸(底層原理是系統棧,有65000層)代替數據結構的棧,使程序代碼更加簡潔(但是在運算符超過65000個時系統棧可能會「爆棧」)。

C語言求解逆波蘭表達式

使用棧完成

int add(char s[])

{

int st[100];

char *p;

int top=-1;

int A,B,sum=0;

for(p=s;*p!=0;p++)//進行數值計算

{

switch (*p)

{

case ‘0’:

case ‘1’:

case ‘2’:

case ‘3’:

case ‘4’:

case ‘5’:

case ‘6’:

case ‘7’:

case ‘8’:

case ‘9’:st[++top]=*p-‘0’;break;//是數字壓入總棧st中

case ‘+’:

case ‘-‘:

case ‘*’:

case ‘/’://是運算符號

A=st[top–];

B=st[top–];//彈出2個數字

switch (*p)

{

case ‘+’:sum=B+A;break;

case ‘-‘:sum=B-A;break;

case ‘*’:sum=B*A;break;

case ‘/’: sum=B/A;break;

}

st[++top]=sum;//將結果重新壓入棧

break;

}

}

return sum;

}

C語言逆波蘭算數表達式

我用c語言寫的wintc下運行正確 希望對你有幫助

#includestdio.h

#includestring.h

int nibolan(char s[])

{ int i=0,a,b;

char *p;

p=s ;

while(*p!=’\0′)

{if(*p==’+’){*p=((*(p-2)-48)+(*(p-1)-48))+48;}

if(*p==’-‘){*p=((*(p-2)-48)-(*(p-1)-48))+48;}

if(*p==’*’){*p=((*(p-2)-48)*(*(p-1)-48))+48;}

if(*p==’/’){*p=((*(p-2)-48)/(*(p-1)-48))+48;}

p++;

} p–;

return (*p)-48;

}

main()

{ int r;

char a[100];

gets(a);

r=nibolan(a);

printf(“%d”,r);

getch();

}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/293189.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-25 18:39
下一篇 2024-12-25 18:39

相關推薦

  • AES加密解密演算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密演算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES演算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演著非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29
  • 台階走法遞歸

    台階走法遞歸是一個經典的遞歸問題,在計算機演算法中有著廣泛的應用。本篇文章將從遞歸的思想出發,詳細分析如何解決這個問題。 一、遞歸基礎知識 遞歸是指一個函數直接或間接地調用自身。遞歸…

    編程 2025-04-29
  • MySQL遞歸函數的用法

    本文將從多個方面對MySQL遞歸函數的用法做詳細的闡述,包括函數的定義、使用方法、示例及注意事項。 一、遞歸函數的定義 遞歸函數是指在函數內部調用自身的函數。MySQL提供了CRE…

    編程 2025-04-29
  • Python語言由荷蘭人為中心的全能編程開發工程師

    Python語言是一種高級語言,很多編程開發工程師都喜歡使用Python語言進行開發。Python語言的創始人是荷蘭人Guido van Rossum,他在1989年聖誕節期間開始…

    編程 2025-04-28
  • Python語言設計基礎第2版PDF

    Python語言設計基礎第2版PDF是一本介紹Python編程語言的經典教材。本篇文章將從多個方面對該教材進行詳細的闡述和介紹。 一、基礎知識 本教材中介紹了Python編程語言的…

    編程 2025-04-28
  • Python語言實現人名最多數統計

    本文將從幾個方面詳細介紹Python語言實現人名最多數統計的方法和應用。 一、Python實現人名最多數統計的基礎 1、首先,我們需要了解Python語言的一些基礎知識,如列表、字…

    編程 2025-04-28

發表回復

登錄後才能評論