申谭 发表于 2023-11-8 00:07:48

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

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

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

输出格式:
对每个表达式输出一行:为一个整数(表达式的值)或为一个字符串INVALID。
#define_CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
char p;
char fu;
long longshu;
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 = -10;
    int lian = 0;
    long long temps;
    int i = 0, m = strlen(p);
    for (i = 0; i < m; i++)
    {
      if (p >= '0' && p <= '9')
      {
            if (!lian)
            {
                tops++;
                shu = p - '0';
            }
            if (lian)
            {
                shu = shu * 10 + p - '0';
            }
            lian++;
      }

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

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

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

Mike_python小 发表于 2023-11-8 00:08:10

代码分析

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

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

问题分析

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

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

建议修改

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

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

球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:}

isdkz 发表于 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;
char fu;
long long shu;

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

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

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

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


希望能帮到你!
页: [1]
查看完整版本: 有一个样例过不了,求大佬分析下代码的逻辑错误