㈠ 表达式求值 栈 运算符优先级表
表达式的求值
问题:能否设计算法,编制一个程序,让计算机扫描如下表达式,并将其值打印出来。
# 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)决定它们的组合方式是从左到右或是从右到左。例如,算术运算符和操作数的组合方式是从左到右,赋值运算符则是从右到左。