sinat_35066848 2016-05-21 14:25 采纳率: 40%
浏览 1602
已采纳

C语言 计算器问题(请大神看一下)

123+213-67*34+345/23*45*(34+34-345+245+567)=359 183
可我的程序等于-363067 代码如下

#include
#include
#include
#define MAXZISE 1000
struct oper
{
char name;
int priority;
int opnum;
};
typedef struct oper OPERATOR;
OPERATOR opStack[MAXZISE];
int OTop=-1;

int numStack[MAXZISE];
int NTop=-1;
int getPriority(char name)//获取一个字符所代表的运算符的优先级
{
if (name=='('||name==')'){
return 0;
}
if (name=='*'||name=='/'){
return 2;
}
if (name=='+'||name=='-'){
return 1;
}
}
int getOpNum(char name)//获取一个字符所代表的运算符的目数
{
if (name=='*'||name=='/'||name=='+'||name=='-'){
return 2;
}
if (name=='('||name==')'){
return 0;
}
}
void pushOp(OPERATOR op)//运算符压栈
{
if (OTop opStack[++OTop] = op;
}
}
OPERATOR popOp()//运算符出栈
{
if (OTop>= 0){
return opStack[OTop--];
}
}
void pushNum(int num)//操作数压栈
{
if (NTop numStack[++NTop] = num;
}
}
int popNum()//操作数出栈
{
if (NTop >= 0){
return numStack[NTop--];
}
}
int change(char s, int *i)//将数字从字符串转换到整型
{
int j = 0;
char str[MAXZISE];
while ((*s) >= '0' && *s <= '9')
{
str[j++] = (*s);
s++;
}
(*i) = (*i) + j;
str[j] = '\0';
return atoi(str);
}
int opertateNum(OPERATOR op)//从操作数栈中弹出两个操作数,完成一次双目运算
{
int num2=popNum();
int num1=popNum();
if (op.name=='+'){
return num1 + num2;
}
if (op.name=='-'){
return num1 - num2;
}
if (op.name=='
'){
return num1 * num2;
}
if (op.name=='/'){
return num1 / num2;
}
}
int main()
{
char S[MAXZISE];
int i,j;
OPERATOR op, topOp;
topOp.name = '#';
topOp.priority = 0;
topOp.opnum = 0;
pushOp(topOp);
scanf("%s", S);
for(i=0;i if(S[i]!=' ')
S[j++]=S[i];
}
S[j]='\0';
for (i=0;S[i]!='\0'&&S[i]!='=';){
if (S[i]>='0'&&S[i]<='9'){
pushNum(change(&S[i], &i));
}
else{
op.name = S[i];
op.priority = getPriority(S[i]);
op.opnum = getOpNum(S[i]);
topOp = popOp();
if (op.name == '('){
//如果是'(',将从栈顶弹出的运算符压回栈内,并将当前运算符则压栈
pushOp(topOp);
pushOp(op);
}
else if (op.name == ')'){
//如果是')',则进行运算,每次运算结果作为一个操作数压入操作数栈,直到将'('弹出运算符栈
while (topOp.name != '('){
pushNum(opertateNum(topOp));
topOp = popOp();
}
}
else{
if (topOp.name !='#'&& op.priority<= topOp.priority){
pushNum(opertateNum(topOp));
}
else{
pushOp(topOp);
}
pushOp(op);
}
i++;
}
}
while ((topOp = popOp()).name!='#'){
pushNum(opertateNum(topOp));
}
printf("%d\n", popNum());
return 0;
}

  • 写回答

5条回答 默认 最新

  • sinat_35066848 2016-05-22 12:30
    关注

    谢谢大家帮忙,程序我已经调出来了
    问题在于运算符的入栈与出栈,碰到 - * + 时,有点小问题,应该继续比较优先级。
    正确代码如下:

    #include
    #include
    #include
    #define MAXZISE 100
    struct oper
    {
    char name;
    int priority;
    int opnum;
    };
    typedef struct oper OPERATOR;
    OPERATOR opStack[MAXZISE];
    int OTop=-1;
    int numStack[MAXZISE];
    int NTop=-1;
    void pushOp(OPERATOR op)//运算符压栈
    {
    if (OTop opStack[++OTop] = op;
    }
    }
    OPERATOR popOp()//运算符出栈
    {
    if (OTop>= 0){
    return opStack[OTop--];
    }
    }
    void pushNum(int num)//操作数压栈
    {
    if (NTop numStack[++NTop] = num;
    }
    }
    int popNum()//操作数出栈
    {
    if (NTop >= 0){
    return numStack[NTop--];
    }
    }
    int getPriority(char name)//获取一个字符所代表的运算符的优先级
    {
    if (name=='('||name==')'){
    return 0;
    }
    if (name=='*'||name=='/'){
    return 3;
    }
    if (name=='-'||name=='+'){
    return 2;
    }
    }
    int getOpNum(char name)//获取一个字符所代表的运算符的目数
    {
    if (name=='*'||name=='/'||name=='+'||name=='-'){
    return 2;
    }
    if (name=='('||name==')'){
    return 0;
    }
    }
    int change(char s, int *i)//将数字从字符串转换到整型
    {
    int j = 0;
    char numstr[MAXZISE];
    while ((*s) >= '0' && *s <= '9')
    {
    numstr[j++] = (*s);
    s++;
    }
    (*i) = (*i) + j;
    numstr[j] = '\0';
    return atoi(numstr);
    }
    int opertateNum(OPERATOR op)//从操作数栈中弹出两个操作数,完成运算
    {
    int num2=popNum();
    int num1=popNum();
    if (op.name=='+'){
    return num1 + num2;
    }
    if (op.name=='-'){
    return num1 - num2;
    }
    if (op.name=='
    '){
    return num1 * num2;
    }
    if (op.name=='/'){
    return num1 / num2;
    }
    }
    int main()
    {
    char S[MAXZISE];
    int i,j;
    OPERATOR op,topOp;
    topOp.name='#';
    topOp.priority=0;
    topOp.opnum=0;
    pushOp(topOp);
    gets(S);
    for(i=0;i if(S[i]!=' ')
    S[j++]=S[i];
    }
    S[j]='\0';
    for(i=0; S[i]!='\0'&&S[i]!='=';){
    if (S[i]>='0'&&S[i]<='9'){
    pushNum(change(&S[i], &i));
    }
    else{
    op.name=S[i];
    op.priority=getPriority(S[i]);
    op.opnum=getOpNum(S[i]);
    topOp=popOp();
    if (op.name=='('){
    //如果是'(',将从栈顶弹出的运算符压回栈内,并将当前运算符则压栈
    pushOp(topOp);
    pushOp(op);
    }
    else if(op.name==')'){
    //如果是')',则进行运算,每次运算结果作为一个操作数压入操作数栈,直到将'('弹出运算符栈
    while (topOp.name!='('){
    pushNum(opertateNum(topOp));
    topOp=popOp();
    }
    }
    else{
    while(topOp.name !='#'&& op.priority<= topOp.priority){
    pushNum(opertateNum(topOp));
    topOp=popOp();
    }
    if(topOp.name =='#'|| op.priority> topOp.priority){
    pushOp(topOp);
    }
    pushOp(op);
    }
    i++;
    }
    }

    while ((topOp=popOp()).name!='#'){
        pushNum(opertateNum(topOp));
    }
    printf("%d\n", popNum());
    return 0;
    

    }

    进行改动的代码是这几行:
    while(topOp.name !='#'&& op.priority<= topOp.priority){
    pushNum(opertateNum(topOp));
    topOp=popOp();
    }
    if(topOp.name =='#'|| op.priority> topOp.priority){
    pushOp(topOp);
    }

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?