㈠ 表達式求值 棧 運算符優先順序表
表達式的求值
問題:能否設計演算法,編制一個程序,讓計算機掃描如下表達式,並將其值列印出來。
# 3 * ( 4 + 8 ) / 2 -5 #
註:給表達式設置#,標志掃描的開始和結束。
提示演算法:設兩個棧,一個是操作數棧,用來存放操作數,如3、4、8等,另一個是運算符棧,用來存放運算符。
首先將標志「#」進運算符棧的棧底。
然後依次掃描,按照棧的後進先出原則進行:
(1)遇到操作數,進操作數棧;
(2)遇到運算符時,則需將此運算符的優先順序與棧頂運算符的優先差簡級比較,
若若高於棧頂元素則進棧,繼續友唯掃描下一符號,
否則,將運算符棧的棧頂元素退棧,形成一個操作碼Q,同時操作數棧的棧頂元素兩次退棧,形成兩個操作數a、b,讓計算機對操作數與操作碼完成一次運算操作,好慶培即aQb,並將其運算結果存放在操作數棧中……
模擬計算機處理算術表達式過程。從鍵盤上輸入算術表達式串(只含+、-、×、÷運算符,充許含括弧),輸出算術表達式的值。設輸入的表達式串是合法的。
附源程序:
program exsj_1;
const
max=100;
var
number:array[0..max] of integer;
symbol:array[1..max] of char;
s,t:string;
i,p,j,code:integer;
procere push;{算符入棧運算}
begin
inc(p);symbol[p]:=s[i];
end;
procere pop;{運算符棧頂元素出棧,並取出操作數棧元素完成相應的運算}
begin
dec(p);
case symbol[p+1] of
'+':inc(number[p],number[p+1]);
'-':dec(number[p],number[p+1]);
'*':number[p]:=number[p]*number[p+1];
'/':number[p]:=number[p] div number[p+1];
end;
end;
function can:boolean;{判斷運算符的優先順序別,建立標志函數}
begin
can:=true;
if (s[i] in ['+','-']) and (symbol[p]<>'(') then exit;
if (s[i] in ['*','/']) and (symbol[p] in ['*','/']) then exit;
can:=false;
end;
begin
write('String : '); readln(s); s:='('+s+')'; i:=1; p:=0;
while i<=length(s) do
begin
while s[i]='(' do {左括弧處理]
begin
push; inc(i);
end;
j:=i;
repeat {取數入操作數棧}
inc(i);
until (s[i]<'0') or (s[i]>'9');
t:=(s,j,i-j); val(t,number[p],code);
repeat
if s[i]=')' then {右括弧處理}
begin
while symbol[p]<>'(' do pop;
dec(p); number[p]:=number[p+1];
end
else
begin {根據標志函數值作運算符入棧或出棧運算處理}
while can do pop;
push;
end;
inc(i);
until (i>length(s)) or (s[i-1]<>')');
end;
write('Result=',number[0]);
readln;
end.
㈡ c語言問題 用一個棧來存符號把數學的中綴表達式計算出來
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100
typedef struct
{
int data[MAX];
int top;
}SeqStack;
SeqStack *Init_SeqStack() //初始化堆棧
{
SeqStack *s;
s=new SeqStack; //申請棧空間
if (!s)
{
printf("空間不足,初始化失敗!");
return NULL; //未申請到足夠大的存儲空間,返回空指針
}
else
{
s->top=-1; //初始化棧頂指針
printf("堆棧初始化成功!\n按回車鍵繼續...");
return s; //申請到棧空間,返回棧空間地址
}
}
int Empty(SeqStack *s){ //判空棧
if (s->top==-1)
return 1; //棧頂指針指向棧底,空棧
else
return 0;
}
int Push(SeqStack *s,int x){ //進棧
if (s->top==MAX-1)
return 0; //棧滿不能入棧,返回錯誤租山代碼0
else
{ s->top++; //棧頂指針向上移動
s->data[s->top]=x; //將x至入新的棧頂
return 1; //入孝型空棧成功,返回成功代碼1
}
}
int Pop(SeqStack *s,int *x){ //出棧
if (Empty(s))
return 0; //棧空不能出棧,返回錯誤代碼0
else
{ *x=s->data[s->top]; //保存棧頂元素值
s->top--; //棧頂指針向巧瞎下移動
return 1; //返回成功代碼1
}
}
int GetTop(SeqStack *s) //取棧頂元素
{
return(s->data[s->top]);
}
int Is_OPND(char x)//判斷運算符和運算數
{
int temp;
temp=1;
switch (x)
{
case '^':
case '*':
case '/':
case '%':
case '+':
case '-':
case '(':
case ')':
case '#':temp=0;
}
return(temp);
}
int Precede(char in,char out)
{
int c_temp1,c_temp2;
int temp;
switch(in)
{
case '^':c_temp1=5;break;
case '*':
case '/':
case '%':c_temp1=4;break;
case '+':
case '-':c_temp1=2;break;
case '(':c_temp1=0;break;
case ')':c_temp1=6;break;
case '#':c_temp1=-1;
}
switch(out)
{
case '^':c_temp2=5;break;
case '*':
case '/':
case '%':c_temp2=3;break;
case '+':
case '-':c_temp2=1;break;
case '(':c_temp2=6;break;
case ')':c_temp2=0;break;
case '#':c_temp2=-1;
}
if (c_temp1<c_temp2) temp=-1;//棧外算符優先順序高,入棧
if (c_temp1==c_temp2) temp=0;
if (c_temp1>c_temp2) temp=1;//棧內算符優先順序高,運算
return(temp);
}
int Execute(int a, char op, int b){
int s;
switch(op){
case '^':s=(int)pow(a,b);break;
case '*':s=a*b;break;
case '/':s=a/b;break;
case '%':s=a%b;break;
case '+':s=a+b;break;
case '-':s=a-b;break;
}
return(s);
}
void main()
{
SeqStack *OPTR, *OPND;//定義兩個棧
int w,op,temp;
int a,b,is_err;
OPTR=Init_SeqStack(); //初始化運算符optr堆棧
OPND=Init_SeqStack(); //初始化運算數opnd堆棧
is_err=Push(OPTR,'#'); //首先將#進運算符棧
system("cls");
printf("------------------中綴表達式求值程序------------------\n\n");
printf("-----使用方法:連續輸入表達式,以#號結束,最後按回車鍵。\n\n");
printf("-----可使用的運算符包括:(、)、^、*、/、%、+、-\n\n");
printf("-----注意:運算數為0-9十個數字。\n\n");
printf("-----請輸入表達式:");
w=getchar();
while(w!='#'||GetTop(OPTR)!='#')//算符棧頂元素不是#(表達式非0,執行語句)
{
if (Is_OPND(w))//w為數值,返回1,w為算符,返回0
{
Push(OPND,w-'0');//數值進opnd堆棧
w=getchar();//循環
}
else
switch(Precede(GetTop(OPTR),w))//否則,比較optr堆棧中棧頂的算符與getchar()函數讀入的算符的優先順序
{
case -1://棧外算符優先順序高,繼續入棧
is_err=Push(OPTR,w);//入棧操作
w=getchar();//循環
break;
case 0://???
is_err=Pop(OPTR,&temp);
w=getchar();
break;
case 1://棧內算符優先順序高
is_err=Pop(OPND,&b);//將棧頂的元素賦予後一個變數
is_err=Pop(OPND,&a);
is_err=Pop(OPTR,&op);
is_err=Push(OPND,Execute(a,op,b));
break;
}
}
printf("-----結果為:%d\n",GetTop(OPND));
加分
㈢ c語言運算符的優先順序順序
c語言運算符優先順序從高到低的順序依次如下:
優先順序從上到下依次遞減,最上面具有最高的優先順序,逗號操作符具有最低的優先順序。表達式的結合次序取決於表達式中各種運算符的優先順序。優先順序高的運算符先結合,優先順序低的運算符後結合,同一行中的運算符的優先順序相同。
不同類型的運算符之間也有相應的優先順序順序:
一個表達式中既可以包括相同類型的運算符,也可以包括不同類型的運算符或者函數。當多種運算符出現在同一個表達式中時,應該先按照不同類型運算符間的優先順序進行運算。
各種運算符間的優先順序如下:
數值運算符、字元串運算符、關系運算符、邏輯運算符。可以用括弧改變優先順序順序,使得括弧內的運算優先於括弧外的運算。對於多重括弧,總是由內到外強製表達式的某些部分優先運行。括弧內的運算總是最優先計算。
㈣ C語言的運算符的優先順序是什麼
1、最高級:出現同級別運算符時的結合方向是從左往右(下面級別沒寫結合順序時,默認是從左往右)。
( )圓括弧
[ ]下標運算符號
->指向結構體成員運算符
.結構體成員運算符
㈤ c++怎麼用棧實現運算符的優先順序比較
首先肯定要設計棧的數據結構,之後設計運算符操作兄團類,這是整體思路。
//mystack.h
#include<iostream>
using namespace std;
template<class T>
class Stack
{
public:
T *data;
int maxSize;
int top;
public:
Stack(int n)
{
data=new T[n];
if(data==NULL)
{cout<<"overflow!\n";exit(1);}
maxSize=n;
top=-1;
}
Stack(){}
~Stack()
{
cout<<"Destroy!"<<endl;
}
//創建空棧
void SetStack(int n);
//棧存在則棧被銷毀
void FreeStack();
//棧存在則返回棧的元素羨游橘個數,即棧的長度
int StackSize();
//判斷棧是否為空
bool StackEmpty();
//判斷棧是否為滿
bool StackFull();
//棧存在且非空則返回棧的棧頂元素
T Peek();
//棧存在則插入元素item為新的棧頂元素
void Push(T item);
//棧 存在且非空則刪除棧的棧頂元素並用e返回其值
T Pop();
//棧存在則清為空棧
void ClearStack();
void PrintStack();
};
//順序棧的實現mystack.cpp
#include "mystack.h"
template<class T>
void Stack<T>::SetStack(int n)
{
data=new T[n];
if(data==NULL)
{cout<<"overflow!\n";exit(1);}
maxSize=n;
top=-1;
}
template<class T>
void Stack<T>::FreeStack()
{free(data);}
template<class T>
int Stack<T>::StackSize()
{return(top+1);}
template<class T>
bool Stack<T>::StackEmpty()
{
if(top==-1)
return true;
return false;
}
template<class T>
bool Stack<T>::StackFull()
{
if(top==maxSize-1)
return true;
return false;
}
template<class T>
T Stack<磨薯T>::Peek()
{
if(top==-1)
{cerr<<"棧已空!\n";exit(1);exit(1);}
return(data[top]);
}
template<class T>
void Stack<T>::Push(T item)
{
if(top==maxSize-1)
{cerr<<"棧已滿!\n";;exit(1);}
top++;
data[top]=item;
}
template<class T>
T Stack<T>::Pop()
{
if(top==-1)
{cerr<<"棧已空!\n";exit(1);}
top--;
return data[top+1];
}
template<class T>
void Stack<T>::ClearStack()
{top=-1;}
template<class T>
void Stack<T>::PrintStack()
{
while(top!=-1)
{
cout<<data[top]<<endl;
top--;
}
}
㈥ c語言運算優先順序
優先順序就是當表達式中有多個運算符時,先計算誰,後計算誰。打個比方,在四則運算中乘除的優先順序就高於加減。
但是C語言中的運算符除了加減乘除還有很多,我們也沒必要將所有運算符的優先順序都記住,這里列出來各個運算符的優先順序表,實在需要用到的時候查一下表就行了。而且實際上在編程的時候需要考慮優先順序的情況很少,因為如果不知道優先順序高低的話,加一個括弧就行了,因為括弧的優先順序是最高的。
比如:
k = (j > i) && (8 == i)
根據優先順序的高低,完全可以寫成:
k = j > i && 8 == i
第一種寫法是比較提倡的,因為一看就知道先計算誰後計算誰,節省了大家的時間還不容易出錯。而且加圓括弧也是一種編程規范,因為程序不只是寫給自己看。
此外運算符還有「目」和「結合性」的概念。「目」就是眼睛的意思,一個運算符需要幾個數參與就歸為「幾目」。C語言中大多數運算符都是雙目的,比如 和 運算符;也有單目和三目的,單目運算符如邏輯非 ( !1 );三目運算符即條件運算符,?:也是C語言中的唯一一個三目運算符。
說完了「目」的概念,再來說一說「結合性」。先來煮個栗子:
1 + 2 × 3 / 4
上式中乘法和除法的優先順序相同,但計算的時候是從左往右,所以乘和除的結合性就是從左往右,so easy!
C語言中大多數運算符的結合性都是從左往右,只有三個運算符是從右往左的。一個是單目運算符,另一個是三目運算符,還有一個就是雙目運算符中的賦值運算符 。運算符的「結合性」也不需要死記硬背,在不斷使用中就記住了。
㈦ 求一段c語言計算程序代碼,要能正確處理裡面運算符的優先計算順序和圓括弧的優先順序。
看來這個問題還沒有搞定啊,我來幫你搞定吧,稍等~
好了,現在搞定,發給你吧~
為了你方便看,就寫在一個cpp文件里了,比較長,三百多行。我已經編譯通過,也做了簡單測試,沒詳細測,如果有bug,你就自己改一下吧。表達式輸入完了之後直接回車,就出結果了,跟平時輸入字元串一樣。
/**********************************************
算術表達式求值的算符優先順序演算法
利用棧來實現括弧匹配和表達式求值
演算法的詳細說明,請查看清華大學出版社《數據結構》,嚴蔚敏&吳偉民著,3.3節
***********************************************/
#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
#defineSTACK_INIT_SIZE100//存儲空間初始分配量
#defineSTACKINCREMENT10//存儲空間分配增量
#defineOK0
#defineERROR127
//定義一個順序棧
typedefstruct
{
int*base;//在棧構造之前和銷毀之後,base的值為NULL
int*top;//棧頂指針
intstacksize;//當前已分配的存儲空間,以元素為單位
}SqStack;intInitStack(SqStack*S)
{
//構造一個空棧
S->base=(int*)malloc(STACK_INIT_SIZE*sizeof(SqStack));
if(NULL==S->base)
{//內存分配失敗
returnERROR;
}
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;
returnOK;
}
charGetTop(SqStack*S,char*element)
{
//若棧不空,取棧頂元素,用element返回
if(S->base==S->top)
{
returnERROR;
}
*element=*(S->top-1);
return*element;
}
intPush(SqStack*S,intelement)
{
//插入元素element為新的棧頂元素
if((S->top-S->base)>S->stacksize)
{//棧滿,追加空間
S->base=(int*)realloc(S->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(SqStack));
if(NULL==S->base)
{
returnERROR;
}
S->top=S->base+S->stacksize;
S->stacksize+=STACKINCREMENT;
}
*S->top++=element;
returnOK;
}
intPop(SqStack*S,int*element)
{
//若棧不為空,則刪除棧頂元素,用element返回其值
if(S->top==S->base)
{
returnERROR;
}
*element=*(--S->top);
returnOK;
}
intPopOPTR(SqStack*S,char*element)
{
if(S->top==S->base)
{
returnERROR;
}
*element=*(--S->top);
returnOK;
}
//判斷字元c是否在集合OP中
intInOP(charc,charOP[7])
{
for(inti=0;i<7;i++)
{
if(c==OP[i])
{
returnOK;
}
}
returnERROR;
}
//判斷運算符的優先順序
intCompare(inta,intb)
{
if('+'==a)
{
switch(b)
{
case'+':
return'>';
case'-':
return'>';
case'*':
return'<';
case'/':
return'<';
case'(':
return'<';
case')':
return'>';
case' ':
return'>';
}
}
if('-'==a)
{
switch(b)
{
case'+':
return'>';
case'-':
return'>';
case'*':
return'<';
case'/':
return'<';
case'(':
return'<';
case')':
return'>';
case' ':
return'>';
}
}
if('*'==a)
{
switch(b)
{
case'+':
return'>';
case'-':
return'>';
case'*':
return'>';
case'/':
return'>';
case'(':
return'<';
case')':
return'>';
case' ':
return'>';
}
}
if('/'==a)
{
switch(b)
{
case'+':
return'>';
case'-':
return'>';
case'*':
return'>';
case'/':
return'>';
case'(':
return'<';
case')':
return'>';
case' ':
return'>';
}
}
if('('==a)
{
switch(b)
{
case'+':
return'<';
case'-':
return'<';
case'*':
return'<';
case'/':
return'<';
case'(':
return'<';
case')':
return'=';
}
}
if(')'==a)
{
switch(b)
{
case'+':
return'>';
case'-':
return'>';
case'*':
return'>';
case'/':
return'>';
case')':
return'>';
case' ':
return'>';
}
}
if(' '==a)
{
switch(b)
{
case'+':
return'<';
case'-':
return'<';
case'*':
return'<';
case'/':
return'<';
case'(':
return'<';
case' ':
return'=';
}
}
returnERROR;
}
//簡單計算
intCalculate(intleft,charoper,intright)
{
intresult=0;
switch(oper)
{
case'+':
result=left+right;
break;
case'-':
result=left-right;
break;
case'*':
result=left*right;
break;
case'/':
result=left/right;
break;
}
returnresult;
}
/**********************************************
算術表達式求值的算符優先順序演算法,設OPTR和OPND分別為運算符棧和運算數棧
OP為運算符集合
**********************************************/
intmain()
{
SqStackOPTR,OPND;
intelement=0;
charOPTR_element;
intleftNum,rightNum;
charinput;//獲取輸入
charOP[7]={'+','-','*','/','(',')',' '};
InitStack(&OPTR);
Push(&OPTR,' ');
InitStack(&OPND);
printf("請輸入表達式 ");
input=getchar();
while(' '!=input||' '!=GetTop(&OPTR,&OPTR_element))
{
inttemp=0;
if(isdigit(input))
{//如果是數字
ungetc(input,stdin);//返回給輸入流
scanf("%d",&temp);
Push(&OPND,temp);//數字就進OPND棧
input=getchar();
continue;
}
if(OK==InOP(input,OP))
{
GetTop(&OPTR,&OPTR_element);
switch(Compare(OPTR_element,input))
{
case'<'://棧頂元素優先順序低
Push(&OPTR,input);//運算符進OPTR棧
input=getchar();
break;
case'='://脫括弧
PopOPTR(&OPTR,&OPTR_element);
input=getchar();
break;
case'>'://退棧,並將運算結果入棧
PopOPTR(&OPTR,&OPTR_element);
Pop(&OPND,&rightNum);
Pop(&OPND,&leftNum);
Push(&OPND,Calculate(leftNum,OPTR_element,rightNum));
break;
default:
printf("表達式括弧不匹配 ");
returnERROR;
}//switch
}//if
else
{
printf("表達式內有未知字元,即將退出 ");
returnERROR;
}
}//while
intvalue;
Pop(&OPND,&value);
printf("結果=%d ",value);
returnOK;
}//end
㈧ C語言裡面的運算符優先順序如何
C語言中,運算符的運算優先順序共分為15 級。1 級最高,15 級最低。 在表達式中,優先順序較高的先於優先順序較低的進行運算。而在一個運算量兩側的運算符 優先順序相同時,則按運算符的結合性所規定的結合方向處理。
各等級運算符如下:
(以下說明中,對傳統的1級和2級做了細化,1和2對應傳統1級,3和4對應傳統2級,所以細化說明共有17級。)
1、基本表達式 1級
基本表達式(Primary expressions),主要是用於運算符之間,做為運算數。
標識,常量,字元串文字量,優先順序提升表達式最優先執行。
優先順序提升表達式是指圓括弧包圍的表達式,如「( expression )」
2、後綴表達式 2級
postfix-expression [ expression ],數組下標運算。
postfix-expression ( argument-expression-list),函數調用,括弧內的參數可選。
postfix-expression . identifier,成員訪問,
postfix-expression -> identifier,成員訪問,->號之前應為指針。
postfix-expression ++,後綴自增
postfix-expression --,後綴自減
( type-name ) { initializer-list }
( type-name ) { initializer-list , } 復合初始化,C99後新增。
3、單目/一元運算 3級
++ unary-expression 前綴自增
-- unary-expression 前綴自減
unary-operator cast-expression 單目轉型表式式, 包括 取地址& ,提領 * , 正號+ ,負號- 位反~ 邏輯否!。
sizeof unary-expression 求類型長度,對表達式求類型長度
sizeof ( type-name ) 求類型長度
4、強制類型表達式 4級
( type-name ) cast-expression,強製表達式成為type-name指定的類型。
5、乘法表達式 5級
「 * 」 乘法運算符;「 / 」除法運算符;「 % 」 取余運算符。
6、加法運算符 6級
「 + 」加法運算符;「 - 」減法運算符。
7、移位運算符 7級
<< 左移運算符;>> 右移運算符。
8、關系運算符 8級
<、<=、>、>=關系運算符。
9、相等運算符 9級
「 == 」等於運算符;「 != 」不等於運算符。
10、位與運算符 10級
「 & 」按位與運算符
11、位異或運算符 11級
「 ∧ 」按位異或運算符(Bitwise exclusive OR operator)。
12、位或運算符 12 級
「 | 」按位或運算符(Bitwise inclusive OR operator)。
13、邏輯與運算符 13級
「&&」邏輯與運算符。
14、邏輯或運算符 14 級
「 || 」邏輯或運算符。
15、三元條件運算符 15級
? :條件運算符。
16、賦值運算符 16 級
=、 +=、 -=、 *=、 /=、 %=、 &=、 ^=、 |=、 <<=、 >>=賦值運算符。
17、逗號運算符 17級
「,」逗號運算符。
具體可參見下圖:
㈨ C語言運算符優先順序順序
C語言運算符優先順序順序如下所示:
(9)c語言用一個棧實現運算符優先擴展閱讀
一個表達式可以包含多個運算符。在這種情況下,運算符的優先順序決定表達式的哪部分被處理為每個運算符的操作數。例如,按照運算規則,表達式中*、/、以及 % 的優先順序比 + 和 - 高。如下列表達式:
a - b * c
相當於 a-(b*c)。如果想讓操作數以不同的方式組合在一起,則必須使用括弧:
(a - b) * c
如果一個表達式中的兩個操作數具有相同的優先順序,那麼它們的結合律(associativity)決定它們的組合方式是從左到右或是從右到左。例如,算術運算符和操作數的組合方式是從左到右,賦值運算符則是從右到左。