求一段c语言计算程序代码,要能正确处理里面运算符的优先计算顺序和圆括号的优先顺序。

比如“ 1+(3-1)*2-(3*(5-3)) ",最后算出的结果会是 -1 。再比如,在程序执行后,随便输入图中的算术表达式,它最后算出的结果会是8,而不是12。请注意,是可以带圆括号的计算程序,括号还得能嵌套。谢谢!!

看来这个问题还没有搞定啊,我来帮你搞定吧,稍等~
好了,现在搞定,发给你吧~
为了你方便看,就写在一个cpp文件里了,比较长,三百多行。我已经编译通过,也做了简单测试,没详细测,如果有bug,你就自己改一下吧。表达式输入完了之后直接回车,就出结果了,跟平时输入字符串一样。
 
/**********************************************
算术表达式求值的算符优先级算法
利用栈来实现括号匹配和表达式求值
算法的详细说明,请查看清华大学出版社《数据结构》,严蔚敏&吴伟民著,3.3节
***********************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define OK 0
#define ERROR 127

//定义一个顺序栈
typedef struct
{
 int *base; //在栈构造之前和销毁之后,base的值为NULL
 int *top;  //栈顶指针
 int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;



int InitStack( SqStack *S )
{
 //构造一个空栈
 S->base = (int *)malloc(STACK_INIT_SIZE *sizeof(SqStack));
 if (NULL == S->base)
 {//内存分配失败
  return ERROR;
 }
 S->top = S->base;
 S->stacksize = STACK_INIT_SIZE;
 return OK;
}


char GetTop( SqStack *S, char *element)
{
 //若栈不空,取栈顶元素,用element返回
 if (S->base == S->top)
 {
  return ERROR;
 }
 *element = *(S->top - 1);
 return *element;
}


int Push( SqStack *S, int element )
{
 //插入元素element为新的栈顶元素
 if ( (S->top - S->base) > S->stacksize )
 {//栈满,追加空间
  S->base = (int *)realloc(S->base, (STACK_INIT_SIZE + STACKINCREMENT)*sizeof(SqStack));
  if ( NULL == S->base )
  {
   return ERROR;
  }
  S->top = S->base + S->stacksize;
  S->stacksize += STACKINCREMENT;
 }
 *S->top++ = element;
 return OK;
}


int Pop( SqStack *S, int *element )
{
 //若栈不为空,则删除栈顶元素,用element返回其值
 if ( S->top == S->base )
 {
  return ERROR;
 }
 *element = * (--S->top);
 return OK;
}


int PopOPTR(SqStack *S, char *element)
{
 if ( S->top == S->base )
 {
  return ERROR;
 }
 *element = * (--S->top);
 return OK;
}


//判断字符c是否在集合OP中
int InOP(char c, char OP[7])
{
 for (int i=0; i<7; i++)
 {
  if ( c == OP[i])
  {
   return OK;
  }
 }
 return ERROR;
}


//判断运算符的优先级
int Compare(int a, int b)
{
 if ( '+' == a )
 {
  switch(b)
  {
  case '+':
   return '>';
  case '-':
   return '>';
  case '*':
   return '<';
  case '/':
   return '<';
  case '(':
   return '<';
  case ')':
   return '>';
  case '\n':
   return '>';
  }
 }
 if ('-' == a)
 {
  switch(b)
  {
  case '+':
   return '>';
  case '-':
   return '>';
  case '*':
   return '<';
  case '/':
   return '<';
  case '(':
   return '<';
  case ')':
   return '>';
  case '\n':
   return '>';
  }
 }
 if ('*' == a)
 {
  switch(b)
  {
  case '+':
   return '>';
  case '-':
   return '>';
  case '*':
   return '>';
  case '/':
   return '>';
  case '(':
   return '<';
  case ')':
   return '>';
  case '\n':
   return '>';
  }
 }
 if ('/' == a)
 {
  switch(b)
  {
  case '+':
   return '>';
  case '-':
   return '>';
  case '*':
   return '>';
  case '/':
   return '>';
  case '(':
   return '<';
  case ')':
   return '>';
  case '\n':
   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 '\n':
   return '>';
  }
 }
 if ('\n' == a)
 {
  switch(b)
  {
  case '+':
   return '<';
  case '-':
   return '<';
  case '*':
   return '<';
  case '/':
   return '<';
  case '(':
   return '<';
  case '\n':
   return '=';
  }
 }
 return ERROR;
}

//简单计算
int Calculate(int left, char oper, int right)
{
 int result = 0;
 switch(oper)
 {
 case '+':
  result = left + right;
  break;
 case '-':
  result = left - right;
  break;
 case '*':
  result = left * right;
  break;
 case '/':
  result = left / right;
  break;
 }
 return result;
}
 
/**********************************************
算术表达式求值的算符优先级算法,设OPTR和OPND分别为运算符栈和运算数栈
OP为运算符集合
**********************************************/
int main()
{
 SqStack OPTR, OPND;
 int element = 0;
 char OPTR_element;
 int leftNum, rightNum;
 char input;//获取输入
 char OP[7] = {'+', '-', '*', '/', '(', ')', '\n'};
 InitStack(&OPTR);
 Push(&OPTR, '\n');
 InitStack(&OPND);
 printf("请输入表达式\n");
 input = getchar();
 while ( '\n' != input || '\n' != GetTop(&OPTR, &OPTR_element))
 {
  int temp = 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("表达式括号不匹配\n");
    return ERROR;
   }//switch
  }//if
  else
  {
   printf("表达式内有未知字符,即将退出\n");
   return ERROR;
  }
 }//while
 int value;
 Pop(&OPND, &value);
 printf("结果 = %d\n", value);
 return OK;
}//end

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-08-29
是程序计算运行时接收到的计算式吗?这个一句两句说不清楚,建议查阅“中缀表达式”“后缀表达式”“调度场算法”等相关内容追问

对,程序运行时输入的计算表达式。比如图片上的那种。

追答

我只能说一个大概思路,要写代码的话太长了
先对输入的表达式按照字符识别进行分割和转换,把数字和符号分隔开,数字转换成double型,符号转换成枚举或其他容易处理的类型,整个算式存储在链表或其它容器里
2+4*9/6
分割:
2,+,4,*,9,/,6
这时的表达式称为中缀表达式(因计算符在两操作数中间而得名,由于有运算级(以及其它算式可能还有括号)的问题,所以需要把他转换成后缀表达式(即计算符放置在操作数之后)转换方法见“调度场算法”http://zh.wikipedia.org/wiki/%E8%B0%83%E5%BA%A6%E5%9C%BA%E7%AE%97%E6%B3%95
转换成后缀表达式之后:2,4,9,*,6,/,+

对该表达式从左扫描,遇到计算符时就计算它前面的两个数,然后删掉这个计算符和前面的两个数,将计算结果插入。直到最后应该只剩一个数,那就是结果。比如说上面的式子:
|||2,4,9,*,6,/,+
2|||4,9,*,6,/,+
2,4|||9,*,6,/,+
2,4,9|||*,6,/,+ 遇到*号计算4*9
2,36|||6,/,+
2,36,6|||/,+ 遇到/号计算36/6
2,6|||+遇到+号计算2+6
8 计算出结果

追问

呵呵,思路都写了这么多,换成具体代码不更好么。不过我的直觉告诉我这些思路似乎对圆括号没多少帮助。如果不考虑圆括号的话,只有加减乘除的代码我早都编成功了,才30多行的代码。。。来嘛帅哥,帮我把程序编出来。谢了!

追答

    这个思路对圆括号有帮助,见“调度场算法”的详细内容,里面有对括号的处理

    代码我现在真的没有功夫写了(这个目测代码量有200行+)抱歉

第2个回答  2013-08-29
怎么意思 能说的清楚点吗 没理解没法做啊 是有固定公式吗 ?追问

编好代码以后运行程序,随便输入一些数字和运算符比如: 3+2*5-4*1 。。。。程序会计算出结果。要能带圆括号的那种,圆括号最优先,且能嵌套

第3个回答  2013-08-29
在网上搜:C语言四则运算

求c语言中关系运算符,逻辑运算符等等各种运算符的优先级!
1级优先级:左结合运算符(圆括号()、下标运算符[]、结构体成员运算符->、类型转换运算符(类型)、指针运算符*、地址与运算符&、sizeof长度运算符)2级优先级:结构体成员运算符(右结合)3级优先级:左结合运算符(逻辑非运算符!、按位取反运算符~、自增运算符++、自减运算符--、负号运算符-...

c语言运算符优先级
c语言运算符的优先级顺序:括号运算符、一元运算符、算术运算符、移位运算符、关系运算符。1、括号运算符 括号运算符具有最高的优先级,它可以改变其他运算符的优先级顺序。使用括号可以明确表达式的计算顺序。2、一元运算符 一元运算符包括++(递增)、--(递减)、!(逻辑非)、+(正号)、-(负号)...

C语言中算术运算符优先级的问题
C语言中算术运算符优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。表达式的结合次序取决于表达式中各种运算符的优先级。优先级高的运算符先结合,优先级低的运算符后结合,同一行中的运算符的优先级相同。基本的优先级:1、指针最优,单目运算优于双目运算。2、先运算...

c语言中运算符的优先级是如何排列的?
第一级:圆括号【()】、下标运算符【[]】、分量运算符的指向结构体成员运算符【->】、结构体成员运算符【.】。第二级:逻辑非运算符【!】、按位取反运算符【~】、自增自减运算符【++ --】、负号运算符【-】、类型转换运算符【(类型)】、指针运算符和取地址运算符【*和&】、长度运算符【...

c语言逻辑运算符,关系运算符,算术运算符,园括号的优先级是怎么样的
位或(|)"三分天下"八九十;逻辑或跟与; \/\/逻辑运算符:|| 和 && 十二和十一; \/\/注意顺序:优先级(||) 底于 优先级(&&)条件高于赋值, \/\/三目运算符优先级排到13 位只比赋值运算符和","高 逗号运算级最低! \/\/逗号运算符优先级最低 ...

c语言运算符优先级顺序表
C语言中,运算符的优先级可以分为不同级别,具体优先级顺序如下:最高优先级:单目运算符(如取反、乘方等)、赋值运算符(=、+=、-=、*=等)、逻辑非运算符(!)、关系运算符(<、<=、>、>=等)、相等运算符(==、!=等)、按位与运算符(&)、按位异或运算符(^)、按位或运算符(|...

求,C语言中各个运算符之间的优先级关系
在C语言中,理解运算符之间的优先级关系是编写正确代码的关键。以下是按照优先级排序的运算符列表,从最高优先级到最低优先级:1. **左结合**:() 圆括号,[] 下标运算符,-> 指向结构体成员运算符,. 结构体成员运算符 2. **右结合**:! 逻辑非运算符,~ 按位取反运算符,前缀增量运算符...

c语言运算符优先级顺序表
第1优先级:各种括号,如()、[]等、成员运算符 . ;第2优先级:所有单目运算符,如++、–、!、~等;第3优先级:乘法运算符*、除法运算符\/、求余运算符%;第4优先级:加法运算符+、减法运算符-;第5优先级:移位运算符<<、>>;第6优先级:大于运算符>、大于等于运算符>=、小于运<、...

C语言运算符的优先级
1、C语言中,运算符的运算优先级共分为15级。1级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。2、c语言运算符优先级从高到低的顺序依次如下:优先级从上到下依次递减,最上面具有最高...

C语言的运算符的优先级是什么?
逻辑与&&优先级大于逻辑或||。8、第八级:? :也称为条件运算符号,是C语言中唯一的一个三目运算符,结合顺序是从右往左。9、第九级:=、+=、-+、*=、\/=、%= 这些运算符也叫做赋值运算符,除此之外,>>=、<<=、&=、^=、|=这些赋值运算符也在这一级别内,结合顺序是从右往左。&...

相似回答