鱼C论坛

 找回密码
 立即注册
查看: 324|回复: 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 。

修正后的代码如下:

  1. #include <stdio.h>
  2. #include <string.h>

  3. char p[100001];
  4. char fu[100001];
  5. long long shu[100001];

  6. int youxian(char a) {
  7.     if (a == '+') return 1;
  8.     if (a == '-') return 1;
  9.     if (a == '*') return 2;
  10.     if (a == '/') return 2;
  11.     if (a == '^') return 3;
  12.     if (a == '(') return 0;
  13.     return -1;
  14. }

  15. int caozuo(int a, int b, char s) {
  16.     switch (s) {
  17.         case '+': return a + b;
  18.         case '-': return a - b;
  19.         case '*': return a * b;
  20.         case '/': if (!b) return -1000000;
  21.                   else return a / b;
  22.         case '^': int result = 1;
  23.                   while (b > 0) {
  24.                       if (b & 1) result *= a;
  25.                       b >>= 1;
  26.                       a *= a;
  27.                   }
  28.                   return result;
  29.     }
  30.     return 0;
  31. }

  32. void change_() {
  33.     int tops = -1, topf = -1;
  34.     fu[0] = -10;
  35.     int lian = 0;
  36.     long long temps;
  37.     int i = 0, m = strlen(p);
  38.     for (i = 0; i < m; i++) {
  39.         if (p[ i] >= '0' && p[ i] <= '9') {
  40.             if (!lian) {
  41.                 tops++;
  42.                 shu[tops] = p[ i] - '0';
  43.             } else {
  44.                 shu[tops] = shu[tops] * 10 + p[ i] - '0';
  45.             }
  46.             lian++;
  47.         } else {
  48.             lian = 0;
  49.             if (youxian(p[ i]) > youxian(fu[topf]) || p[ i] == '(') {
  50.                 topf++;
  51.                 fu[topf] = p[ i];
  52.             } else if (p[ i] == ')') {
  53.                 int j;
  54.                 lian = 0;
  55.                 for (j = topf; fu[j] != '('; j--) {
  56.                     temps = caozuo(shu[tops - 1], shu[tops], fu[j]);
  57.                     if (temps == -1000000) {
  58.                         printf("INVALID\n");
  59.                         return;
  60.                     } else {
  61.                         tops -= 1;
  62.                         shu[tops] = temps;
  63.                     }
  64.                 }
  65.                 topf = j - 1;
  66.             } else {
  67.                 while (topf >= -1 && youxian(p[ i]) <= youxian(fu[topf])) {
  68.                     temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
  69.                     if (temps == -1000000) {
  70.                         printf("INVALID\n");
  71.                         return;
  72.                     } else {
  73.                         tops -= 1;
  74.                         shu[tops] = temps;
  75.                     }
  76.                     topf--;
  77.                 }
  78.                 fu[++topf] = p[ i];
  79.             }
  80.         }
  81.     }

  82.     while (topf != -1) {
  83.         temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
  84.         if (temps == -1000000) {
  85.             printf("INVALID\n");
  86.             return;
  87.         } else {
  88.             tops -= 1;
  89.             shu[tops] = temps;
  90.         }
  91.         topf--;
  92.     }

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

  96. int main() {
  97.     while (scanf("%s", p) != EOF) {
  98.         change_();
  99.     }
  100.     return 0;
  101. }
复制代码


希望能帮到你!
想知道小甲鱼最近在做啥?请访问 -> 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 。

修正后的代码如下:

  1. #include <stdio.h>
  2. #include <string.h>

  3. char p[100001];
  4. char fu[100001];
  5. long long shu[100001];

  6. int youxian(char a) {
  7.     if (a == '+') return 1;
  8.     if (a == '-') return 1;
  9.     if (a == '*') return 2;
  10.     if (a == '/') return 2;
  11.     if (a == '^') return 3;
  12.     if (a == '(') return 0;
  13.     return -1;
  14. }

  15. int caozuo(int a, int b, char s) {
  16.     switch (s) {
  17.         case '+': return a + b;
  18.         case '-': return a - b;
  19.         case '*': return a * b;
  20.         case '/': if (!b) return -1000000;
  21.                   else return a / b;
  22.         case '^': int result = 1;
  23.                   while (b > 0) {
  24.                       if (b & 1) result *= a;
  25.                       b >>= 1;
  26.                       a *= a;
  27.                   }
  28.                   return result;
  29.     }
  30.     return 0;
  31. }

  32. void change_() {
  33.     int tops = -1, topf = -1;
  34.     fu[0] = -10;
  35.     int lian = 0;
  36.     long long temps;
  37.     int i = 0, m = strlen(p);
  38.     for (i = 0; i < m; i++) {
  39.         if (p[ i] >= '0' && p[ i] <= '9') {
  40.             if (!lian) {
  41.                 tops++;
  42.                 shu[tops] = p[ i] - '0';
  43.             } else {
  44.                 shu[tops] = shu[tops] * 10 + p[ i] - '0';
  45.             }
  46.             lian++;
  47.         } else {
  48.             lian = 0;
  49.             if (youxian(p[ i]) > youxian(fu[topf]) || p[ i] == '(') {
  50.                 topf++;
  51.                 fu[topf] = p[ i];
  52.             } else if (p[ i] == ')') {
  53.                 int j;
  54.                 lian = 0;
  55.                 for (j = topf; fu[j] != '('; j--) {
  56.                     temps = caozuo(shu[tops - 1], shu[tops], fu[j]);
  57.                     if (temps == -1000000) {
  58.                         printf("INVALID\n");
  59.                         return;
  60.                     } else {
  61.                         tops -= 1;
  62.                         shu[tops] = temps;
  63.                     }
  64.                 }
  65.                 topf = j - 1;
  66.             } else {
  67.                 while (topf >= -1 && youxian(p[ i]) <= youxian(fu[topf])) {
  68.                     temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
  69.                     if (temps == -1000000) {
  70.                         printf("INVALID\n");
  71.                         return;
  72.                     } else {
  73.                         tops -= 1;
  74.                         shu[tops] = temps;
  75.                     }
  76.                     topf--;
  77.                 }
  78.                 fu[++topf] = p[ i];
  79.             }
  80.         }
  81.     }

  82.     while (topf != -1) {
  83.         temps = caozuo(shu[tops - 1], shu[tops], fu[topf]);
  84.         if (temps == -1000000) {
  85.             printf("INVALID\n");
  86.             return;
  87.         } else {
  88.             tops -= 1;
  89.             shu[tops] = temps;
  90.         }
  91.         topf--;
  92.     }

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

  96. int main() {
  97.     while (scanf("%s", p) != EOF) {
  98.         change_();
  99.     }
  100.     return 0;
  101. }
复制代码


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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 14:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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