鱼C论坛

 找回密码
 立即注册
查看: 560|回复: 2

[已解决]有一个样例过不了,求大佬分析下代码的逻辑错误

[复制链接]
发表于 2023-11-8 00:07:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
给定一个中缀表达式,请编写程序计算该表达式的值。表达式包含+、-、*、\、^、(、),所有运算均为二元运算,操作数均为正整数,但可能不止一位,不超过10位。运算结果为整数,值域为[−2
31
,2
31
)。除法运算结果若为小数则进行截尾取整。若除法运算中除数为0,则输出INVALID。幂运算须自行实现,不允许调用pow等系统函数。测试数据保证幂运算中指数为非负,底数不为0。

输入格式:
输入为多行,每行为一个长度不超过1000的字符串,表示中缀表达式。

输出格式:
对每个表达式输出一行:为一个整数(表达式的值)或为一个字符串INVALID。
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
char p[100001];
char fu[100001];
long long  shu[100001];
int youxian(char a)
{
    if (a == '+') return 1;
    if (a == '-') return 1;
    if (a == '*') return 2;
    if (a == '/') return 2;
    if (a == '^') return 3;
    if (a == '(') return 0;
    return -1;
}
int caozuo(int a, int b, char s)
{
    switch (s)
    {
    case'+': return a + b;
    case'-': return a - b;
    case'*': return a * b;
    case'/': if (!b) return -1000000;
           else   return a / b;
    case'^':  int result = 1;
        while (b > 1) {
            if (b & 1) result *= a;
            b >>= 2, a *= a;
        }
        return result * a;

    }
    return 0;
}
void change_()
{
    int tops = -1, topf = -1;
    fu[0] = -10;
    int lian = 0;
    long long temps;
    int i = 0, m = strlen(p);
    for (i = 0; i < m; i++)
    {
        if (p[i] >= '0' && p[i] <= '9')
        {
            if (!lian)
            {
                tops++;
                shu[tops] = p[i] - '0';
            }
            if (lian)
            {
                shu[tops] = shu[tops] * 10 + p[i] - '0';
            }
            lian++;
        }

        else {
            lian = 0;
            if (youxian(p[i]) > youxian(fu[topf]) || p[i] == '(')
            {
                topf++;
                fu[topf] = p[i];
            }
            else if (p[i] == ')')
            {
                int j;
                lian = 0;
                for (j = topf; fu[j] != '('; j--)
                {
                    temps = caozuo(shu[tops - 1], shu[tops], fu[j]);
                    if (temps == -1000000)
                    {
                        printf("INVALID\n");
                        return;
                    }
                    else
                    {
                        tops -= 1;
                        shu[tops] = temps;
                    }
                }
                topf = j - 1;
            }
            else {
                while (topf >= -1 && youxian(p[i]) <= youxian(fu[topf]))
                {
                    temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
                    if (temps == -1000000)
                    {
                        printf("INVALID\n");
                        return;
                    }
                    else
                    {
                        tops -= 1;
                        shu[tops] = temps;
                    }
                    topf--;
                }
                fu[++topf] = p[i];
            }
        }
    }
   

        while (topf != -1)
        {
            temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
            if (temps == -1000000)
            {
                printf("INVALID\n");
                return;
            }
            else
            {
                tops -= 1;
                shu[tops] = temps;
            }
            topf--;
        }
        printf("%lld\n", shu[0]);
        return;
}
int main()
{

    while (scanf("%s", p) != EOF)
    {
        change_();
    }
    return 0;
}
最佳答案
2023-11-8 00:11:15
这段代码实现了一个计算中缀表达式的程序。它首先定义了一个优先级函数 youxian ,用于判断运算符的优先级。然后定义了一个计算函数 caozuo ,根据运算符对两个操作数进行计算。接下来定义了一个转换函数 change_ ,用于将中缀表达式转换为后缀表达式并计算结果。最后在主函数中循环读取输入的中缀表达式,并调用转换函数进行计算。

转换函数 change_ 的实现逻辑如下:
1. 初始化一个操作数栈 shu 和一个运算符栈 fu ,并定义两个栈的栈顶指针 tops 和 topf 。
2. 遍历中缀表达式的每个字符:
   · 如果是数字字符,则将其转换为整数并入栈 shu 。
   · 如果是运算符:
     · 如果当前运算符的优先级大于栈顶运算符的优先级或是左括号,则将当前运算符入栈 fu 。
     · 如果是右括号,则将栈顶运算符出栈并进行运算,直到遇到左括号为止。
     · 否则,将栈顶运算符出栈并进行运算,直到栈为空或当前运算符的优先级大于栈顶运算符的优先级。
3. 当遍历结束后,如果运算符栈不为空,则将栈中的运算符依次出栈并进行运算,直到栈为空。
4. 最后,输出操作数栈中的结果。

这段代码的逻辑基本正确,但是存在两个问题:
1. 在进行除法运算时,没有对除数为0的情况进行处理。需要在除法运算之前判断除数是否为0,如果为0则输出"INVALID"。
2. 在进行幂运算时,计算幂的逻辑有误。应该使用 b >>= 1 而不是 b >>= 2 ,并且在循环结束后需要将结果乘以底数 a 。

修正后的代码如下:
#include <stdio.h>
#include <string.h>

char p[100001];
char fu[100001];
long long shu[100001];

int youxian(char a) {
    if (a == '+') return 1;
    if (a == '-') return 1;
    if (a == '*') return 2;
    if (a == '/') return 2;
    if (a == '^') return 3;
    if (a == '(') return 0;
    return -1;
}

int caozuo(int a, int b, char s) {
    switch (s) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': if (!b) return -1000000;
                  else return a / b;
        case '^': int result = 1;
                  while (b > 0) {
                      if (b & 1) result *= a;
                      b >>= 1;
                      a *= a;
                  }
                  return result;
    }
    return 0;
}

void change_() {
    int tops = -1, topf = -1;
    fu[0] = -10;
    int lian = 0;
    long long temps;
    int i = 0, m = strlen(p);
    for (i = 0; i < m; i++) {
        if (p[ i] >= '0' && p[ i] <= '9') {
            if (!lian) {
                tops++;
                shu[tops] = p[ i] - '0';
            } else {
                shu[tops] = shu[tops] * 10 + p[ i] - '0';
            }
            lian++;
        } else {
            lian = 0;
            if (youxian(p[ i]) > youxian(fu[topf]) || p[ i] == '(') {
                topf++;
                fu[topf] = p[ i];
            } else if (p[ i] == ')') {
                int j;
                lian = 0;
                for (j = topf; fu[j] != '('; j--) {
                    temps = caozuo(shu[tops - 1], shu[tops], fu[j]);
                    if (temps == -1000000) {
                        printf("INVALID\n");
                        return;
                    } else {
                        tops -= 1;
                        shu[tops] = temps;
                    }
                }
                topf = j - 1;
            } else {
                while (topf >= -1 && youxian(p[ i]) <= youxian(fu[topf])) {
                    temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
                    if (temps == -1000000) {
                        printf("INVALID\n");
                        return;
                    } else {
                        tops -= 1;
                        shu[tops] = temps;
                    }
                    topf--;
                }
                fu[++topf] = p[ i];
            }
        }
    }

    while (topf != -1) {
        temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
        if (temps == -1000000) {
            printf("INVALID\n");
            return;
        } else {
            tops -= 1;
            shu[tops] = temps;
        }
        topf--;
    }

    printf("%lld\n", shu[0]);
    return;
}

int main() {
    while (scanf("%s", p) != EOF) {
        change_();
    }
    return 0;
}

希望能帮到你!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-11-8 00:08:10 | 显示全部楼层

回帖奖励 +5 鱼币

代码分析

这段代码实现了一个计算中缀表达式的值的功能,主要通过栈来处理运算符和操作数。

1. youxian 函数用于返回运算符的优先级,其中负数表示非法的运算符。
2. caozuo 函数用于执行运算,包括加减乘除和幂运算。
3. change_ 函数实现了中缀表达式的计算逻辑,通过栈来存储操作数和运算符,并按照优先级依次进行计算。
4. main 函数则是通过循环读入输入的中缀表达式,并调用 change_ 函数进行计算并输出结果。

问题分析

在你提供的代码中,有几个可能会导致程序出错的地方需要仔细检查:

1. 幂运算的实现部分可能存在问题,需要仔细检查幂运算的逻辑和实现是否正确。
2. 对于除数为 0 的情况,代码中使用了特定的数值 -1000000 来表示无效结果,这样的处理方式不够规范和清晰,容易引起逻辑错误。
3. 输入处理部分可能存在问题,需要确认输入的格式和内容是否符合预期。

建议修改

1. 处理幂运算时,推荐使用更加清晰且符合常规算法的实现方式,确保逻辑正确。
2. 对于除数为 0 的情况,可以考虑使用错误码或者异常处理来更好地表示无效结果。
3. 在输入处理部分,可以添加对输入格式的校验和异常处理,以确保程序能够正常处理各种情况下的输入。

希望以上分析和建议可以帮助您找到问题并改进代码。如果您需要更多帮助或有其他问题,请随时告诉我。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-8 00:11:15 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +5 鱼币

这段代码实现了一个计算中缀表达式的程序。它首先定义了一个优先级函数 youxian ,用于判断运算符的优先级。然后定义了一个计算函数 caozuo ,根据运算符对两个操作数进行计算。接下来定义了一个转换函数 change_ ,用于将中缀表达式转换为后缀表达式并计算结果。最后在主函数中循环读取输入的中缀表达式,并调用转换函数进行计算。

转换函数 change_ 的实现逻辑如下:
1. 初始化一个操作数栈 shu 和一个运算符栈 fu ,并定义两个栈的栈顶指针 tops 和 topf 。
2. 遍历中缀表达式的每个字符:
   · 如果是数字字符,则将其转换为整数并入栈 shu 。
   · 如果是运算符:
     · 如果当前运算符的优先级大于栈顶运算符的优先级或是左括号,则将当前运算符入栈 fu 。
     · 如果是右括号,则将栈顶运算符出栈并进行运算,直到遇到左括号为止。
     · 否则,将栈顶运算符出栈并进行运算,直到栈为空或当前运算符的优先级大于栈顶运算符的优先级。
3. 当遍历结束后,如果运算符栈不为空,则将栈中的运算符依次出栈并进行运算,直到栈为空。
4. 最后,输出操作数栈中的结果。

这段代码的逻辑基本正确,但是存在两个问题:
1. 在进行除法运算时,没有对除数为0的情况进行处理。需要在除法运算之前判断除数是否为0,如果为0则输出"INVALID"。
2. 在进行幂运算时,计算幂的逻辑有误。应该使用 b >>= 1 而不是 b >>= 2 ,并且在循环结束后需要将结果乘以底数 a 。

修正后的代码如下:
#include <stdio.h>
#include <string.h>

char p[100001];
char fu[100001];
long long shu[100001];

int youxian(char a) {
    if (a == '+') return 1;
    if (a == '-') return 1;
    if (a == '*') return 2;
    if (a == '/') return 2;
    if (a == '^') return 3;
    if (a == '(') return 0;
    return -1;
}

int caozuo(int a, int b, char s) {
    switch (s) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': if (!b) return -1000000;
                  else return a / b;
        case '^': int result = 1;
                  while (b > 0) {
                      if (b & 1) result *= a;
                      b >>= 1;
                      a *= a;
                  }
                  return result;
    }
    return 0;
}

void change_() {
    int tops = -1, topf = -1;
    fu[0] = -10;
    int lian = 0;
    long long temps;
    int i = 0, m = strlen(p);
    for (i = 0; i < m; i++) {
        if (p[ i] >= '0' && p[ i] <= '9') {
            if (!lian) {
                tops++;
                shu[tops] = p[ i] - '0';
            } else {
                shu[tops] = shu[tops] * 10 + p[ i] - '0';
            }
            lian++;
        } else {
            lian = 0;
            if (youxian(p[ i]) > youxian(fu[topf]) || p[ i] == '(') {
                topf++;
                fu[topf] = p[ i];
            } else if (p[ i] == ')') {
                int j;
                lian = 0;
                for (j = topf; fu[j] != '('; j--) {
                    temps = caozuo(shu[tops - 1], shu[tops], fu[j]);
                    if (temps == -1000000) {
                        printf("INVALID\n");
                        return;
                    } else {
                        tops -= 1;
                        shu[tops] = temps;
                    }
                }
                topf = j - 1;
            } else {
                while (topf >= -1 && youxian(p[ i]) <= youxian(fu[topf])) {
                    temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
                    if (temps == -1000000) {
                        printf("INVALID\n");
                        return;
                    } else {
                        tops -= 1;
                        shu[tops] = temps;
                    }
                    topf--;
                }
                fu[++topf] = p[ i];
            }
        }
    }

    while (topf != -1) {
        temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
        if (temps == -1000000) {
            printf("INVALID\n");
            return;
        } else {
            tops -= 1;
            shu[tops] = temps;
        }
        topf--;
    }

    printf("%lld\n", shu[0]);
    return;
}

int main() {
    while (scanf("%s", p) != EOF) {
        change_();
    }
    return 0;
}

希望能帮到你!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 18:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表