當前位置:首頁 » 編程語言 » 逆波蘭表達式c語言

逆波蘭表達式c語言

發布時間: 2022-09-05 23:10:39

❶ 將下面的算術運算式表示成逆波蘭式(數據結構 c語言版)

a*b*c → **abc
a*b*c+c*d → +**abc*cd
(a+b)*((c-d)*e+f) → *+ab+*-cdef

上面是波蘭式,逆波蘭式如下:

a*b*c → ab*c*
a*b*c+c*d → ab*c*cd*+
(a+b)*((c-d)*e+f) → ab+cd-e*f+*

寫出(a+b)*((c-d)*e+f)轉換時棧的變化情況:【注意,右端為棧頂】

讀入(,入棧,棧中為(,輸出:(空);
讀入a,直接輸出,棧中為(,輸出:a;
讀入+,入棧,棧中為(+,輸出:a;
讀入b,直接輸出,棧中為(+,輸出:ab;
讀入),依次推出棧中的符號,直到遇見一個(【注意括弧不輸出】,棧中為空,輸出:ab+;
讀入*,入棧,棧中為*,輸出:ab+;
讀入(,入棧,棧中為*(,輸出:ab+;
讀入(,入棧,棧中為*((,輸出:ab+;
讀入c,直接輸出,棧中為*((,輸出:ab+c;
讀入-,入棧,棧中為*((-,輸出:ab+c;
讀入d,直接輸出,棧中為*((-,輸出:ab+cd;
讀入),依次推出棧中的符號,直到遇見一個(【注意括弧不輸出】,棧中為*(,輸出:ab+cd-;
讀入*,入棧,棧中為*(*,輸出:ab+cd-;
讀入e,直接輸出,棧中為*(*,輸出:ab+cd-e;
讀入+,【由於此時棧中的*的優先順序高於+,所以先將*退棧,然後+入棧】,棧中為*(+,輸出:ab+cd-e*;
讀入f,直接輸出,棧中為*(+,輸出:ab+cd-e*f;
讀入),依次推出棧中的符號,直到遇見一個(【注意括弧不輸出】,棧中為*,輸出:ab+cd-e*f+;
此時讀入已經完畢,棧中還剩一個*,輸出:ab+cd-e*f+*
完畢!

以上就是整個從中綴表達式到後綴表達式的過程,棧的變化情況已經都寫出來了。

❷ C語言 逆波蘭表達式 演算法

#include <stdio.h>
#include <string.h>

int main()
{
double d[100], *dp = d;
int m, k;
char t[50], *tp = t;
char s[100], *c = s;
char* op = "+-*/";
char* fg = "0123456789.";

gets(s);

while(*c) {
if(strchr(op, *c)) {
*tp++ = *c;
k = 0;
}else
if(strchr(fg, *c)) {
sscanf(c, "%lf%n", dp++, &m);
c += m - 1;
++k;
}
++c;
while((dp - d > 1 && k == 2) || !*c && dp - d >= 1) {
switch(*--tp) {
case '+': dp[-2] = dp[-2] + dp[-1]; break;
case '-': dp[-2] = dp[-2] - dp[-1]; break;
case '*': dp[-2] = dp[-2] * dp[-1]; break;
case '/': dp[-2] = dp[-2] / dp[-1]; break;
}
--dp;
}
}
printf("%f", *dp);
}

❸ 算術表達式轉化成逆波蘭式(C語言)

你可以擴展一下。

// 中綴表達式轉化為後綴表達式,僅支持加減乘除運算、操作數為1位十進制非負整數的表達式。
char* infix2postfix(const char *infix, char *postfix)
{
const size_t N = strlen(infix);

if (N == 0 || postfix == NULL)
{
return postfix;
}

stack<char> opcode(N); // 堆棧存放的是操作符

for (size_t i = 0; i < N; i++)
{
switch (infix[i])
{
case '(': // 直接忽略左括弧
break;

case ')': // 彈出操作符
*postfix++ = opcode.pop();
*postfix++ = ' ';
break;

case '+':
case '-':
case '*':
case '/':
opcode.push(infix[i]); // 壓入操作符
break;

default:
if (isdigit(infix[i])) // 如果是數字,直接輸出
{
*postfix++ = infix[i];
*postfix++ = ' ';
}
}
}

return postfix;
}

❹ C語言編寫逆波蘭計算器

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.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);
}

❺ 將一般算術表達式轉化為逆波蘭式(c語言)

內存引用錯誤,一般都是指針沒有初始化。
你的指針sq,沒有初始化,就引用了。呵呵。

=========================================
用指針需要malloc,或者指向一個局部變數。
乾脆直接用變數吧,如tanyuguo所說,Sqstack sq;還要把後面的sq->全部改成sq.
此外,
第一個接受輸入的循環不對。
用標准用法while。

whil((c = getchar()) != '#')
str[i] = c;
後面的代碼沒有看。

給你一個建議:每一步後面加上printf列印當前的一些結果,你就能一步一步調試了。否則,這么長的程序一次找到所有錯誤是不可能的。

❻ 用c語言的棧來編寫逆波蘭公式的程序

如題,代碼如下,歡迎探討!!!
[code=C/C++][/code]
/*
表達式的後綴表示及其求值
*/
#include
<stdio.h>
typedef
int
ElemType;
/*
考慮到char型運算時的隱形提升會溢出,此處定義為int,代價僅浪費了內存空間
*/
#define
MAXNUM
16
struct
stack
{
ElemType
data[MAXNUM];
int
top;
};
void
StackInit(struct
stack
*stack)
{
int
i
=
0;
for(;i
<
MAXNUM;i++)
{
stack->data[i]
=
0;
}
stack->top
=
0;
/*
棧底部從索引0處開始
*/
}
void
StackPush(struct
stack
*stack,ElemType
c)
{
if(MAXNUM
==
stack->top)
/*
棧中元素最多有MAXNUM
-
1個
*/
{
printf("The
stack
is
full
");
return;
}
stack->data[stack->top++]
=
c;
}
ElemType
StackPop(struct
stack
*stack)
{
if(0
==
stack->top)
{
printf("The
stack
is
empty
");
/*
當棧空時,若返回0是錯誤的
*/
return
0;
}
return
stack->data[--stack->top];
}
void
PostfixEvaluation(struct
stack
*stack)
{
return;
/*
這個函數非常簡單了,所有的麻煩都已經解決了,我實在不想完成它
*/
}
int
ChangeToPostfix(char
*str)
{
int
i
=
0,flag
=
0;
/*
flag
用來標記連續數字的出現,沒想到好點的辦法
*/
int
c,ch;
struct
stack
ch_stack;
struct
stack
op_stack;
StackInit(&ch_stack);
StackInit(&op_stack);
while(
!=
(c
=
*(str
+
i)))
/*
此處需注意的是:如果是靜態的字元串,以為結束條件,如果是用戶輸入的,則以
』為結束條件
*/
{
if((*
==
c)
||
(/
==
c)
||
((
==
c))
{
flag
=
0;
StackPush(&op_stack,c);
}
else
if()
==
c)
{
flag
=
0;
while((
!=
(c
=
StackPop(&op_stack)))
{
StackPush(&ch_stack,c);
}
if(0
==
op_stack.top)
{
printf("the
(
hasnt
found
when
the
)
come
in!
");
return
-1;
}
}
else
if((+
==
c)||
(-
==
c))
{
flag
=
0;
/*
+和-優先順序低,運算符棧中的((如果存在)後的所有運算符需推出
*/
if(0
!=
op_stack.top)
/*
你可以不在此處添加top的檢查,那樣,你可以發現
StackPop錯誤返回的0被拾取了
*/
{
/*
被逼無奈,只得在此檢查top值,無法寄希望於StackPop了
*/
while((
!=
(ch
=
StackPop(&op_stack)))
{
StackPush(&ch_stack,ch);
if(0
==
op_stack.top)
{
break;
}
}
}
StackPush(&op_stack,c);
}
else
if((c
>=
0)
&&
(c
<=
9))
/*
對於表達式中2位或多位連續的數字,需特殊處理
*/
{
if(0
==
flag)
{
StackPush(&ch_stack,(c
-
0));
flag
=
1;
}
else
{
StackPush(&ch_stack,10
*
StackPop(&ch_stack)
+
(c
-
0));
}
}
i++;
}
while(0
!=
op_stack.top)
/*
表達式處理結束,將運算符棧中的所有運算符推出並壓入字元棧
*/
{
StackPush(&ch_stack,StackPop(&op_stack));
}
PostfixEvaluation(&ch_stack);
/*
該函數放在此處可能較為欠妥,可是,只要完成了任務不就OK了么,難道你會在乎?
*/
/*just
test
*/
for(i
=
0;i
<
ch_stack.top;i++)
{
if(+
==
ch_stack.data[i])
{
printf("+..");
}
else
if(-
==
ch_stack.data[i])
{
printf("-..");
}
else
if(*
==
ch_stack.data[i])
{
printf("*..");
}
else
if(/
==
ch_stack.data[i])
{
printf("/..");
}
else
{
printf("%d..",ch_stack.data[i]);
}
}
return
0;
}
int
main(void)
{
char
str[]
=
"12
+
34
*
435
-
5
/
1";
/*
just
test
*/
printf("The
result
should
be
:
");
printf("12
34
435
*
+
5
1
/
-
[=
8]
");
if(-1
==
ChangeToPostfix(str))
{
printf("ChangeToPostfix()
error
");
return
1;
}
return
0;
}

❼ C語言中有表達式,逆波蘭二詞,何為表達式,何為逆波蘭,誰能告訴我一下,謝謝啦

運算符置於其運算對象之後,這種表達式就是逆波蘭表達式。如:a=1+3 ---> a=1,3 +

❽ 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;i<n;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;i<m;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;i<m;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語言求解逆波蘭表達式

使用棧完成
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下運行正確 希望對你有幫助
#include<stdio.h>
#include<string.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();
}

熱點內容
ios應用上傳 發布:2024-09-08 09:39:41 瀏覽:438
ios儲存密碼哪裡看 發布:2024-09-08 09:30:02 瀏覽:869
opensslcmake編譯 發布:2024-09-08 09:08:48 瀏覽:653
linux下ntp伺服器搭建 發布:2024-09-08 08:26:46 瀏覽:744
db2新建資料庫 發布:2024-09-08 08:10:19 瀏覽:173
頻率計源碼 發布:2024-09-08 07:40:26 瀏覽:780
奧迪a6哪個配置帶後排加熱 發布:2024-09-08 07:06:32 瀏覽:101
linux修改apache埠 發布:2024-09-08 07:05:49 瀏覽:209
有多少個不同的密碼子 發布:2024-09-08 07:00:46 瀏覽:566
linux搭建mysql伺服器配置 發布:2024-09-08 06:50:02 瀏覽:995