【发布时间】:2021-03-20 05:22:57
【问题描述】:
我做了一个评估表达式的程序,例如
Enter text: 97+74/51-98-11+68-34-2-22+73/40+81/15+100
输出:
105.36
如果提供任何错误数据,用户会收到回复Incorrect input
我想知道是否可以将所有 for 循环替换为递归,但我不知道如何实现。有人可以帮忙吗?
任何帮助将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<math.h>
int my_atoi(const char* tab, int from, int to)
{
int score = 0;
int minus = 0;
for (int i = from; i <= to; i++)
{
if (*(tab + i) == 10)
break;
if (*(tab + i) == 32)
break;
if (*(tab + i) == '-' && from == i)
{
minus = 1;
continue;
}
if (*(tab + i) == '+' && i == from)
{
continue;
}
if (*(tab + i) > '9' || *(tab + i) < '0')
break;
else if (*(tab + i) >= '0' && *(tab + i) <= '9')
{
score *= 10;
score += (*(tab + i) - '0');
}
}
if (minus == 1)
score *= -1;
return score;
}
int validate_expression(const char* expr)
{
if (!expr)return -1;
int lng = strlen(expr) - 1;
if (*(expr) > '9' || *(expr) < '0' || * (expr + lng) > '9' || *(expr + lng) < '0')return 0;
int flaga = 0; // flag
for (int i = 1; i < lng; i++) {
if (*(expr + i) <= '9' && *(expr + i) >= '0')
{
flaga = 0;
}
else if (*(expr + i) == '/' || *(expr + i) == '*' || *(expr + i) == '-' || *(expr + i) == '+')
{
if (flaga == 1)
return 0;
flaga = 1;
}
else
return 0;
}
return 1;
}
int calculate(const char* expr, float* result)
{
if (!expr || !result || !validate_expression(expr)) return 0;
if (strpbrk(expr, "i") != NULL) return 0;
int index = 0;
float score = 0;
char sign_memory = 'A';
int flaga = 0;
unsigned int i = 1;
for (; i <= strlen(expr); i++) {
if (*(expr + i) == '-' || *(expr + i) == '+' || *(expr + i) == '/' || *(expr + i) == '*' || *(expr + i) == '\0') {
score += (int)my_atoi(expr, index, i - 1);
index = i;
break;
}
}
for (; i <= strlen(expr); i++) {
if (*(expr + i) == '-' || *(expr + i) == '+' || *(expr + i) == '/' || *(expr + i) == '*' || i == strlen(expr)) {
flaga = 1;
if (sign_memory == '+')
score += (int)my_atoi(expr, index, i - 1);
else if (sign_memory == '-')
score -= (int)my_atoi(expr, index, i - 1);
else if (sign_memory == '/')
{
if (my_atoi(expr, index, i - 1) == 0)return 0;
score /= (int)my_atoi(expr, index, i - 1);
}
else if (sign_memory == '*')
score *= (int)my_atoi(expr, index, i - 1);
sign_memory = *(expr + i);
}
else if (*(expr + i) <= '9' && *(expr + i) >= '0' && flaga == 1) {
flaga = 0;
index = i;
}
}
*result = score;
return 1;
}
int main()
{
char tab[201];
float result, * pointer = &result;
printf("Enter text: ");
fgets(tab, sizeof(tab), stdin);
*(tab + strlen(tab) - 1) = '\0';
if (!validate_expression(tab))
{
printf("Incorrect input");
return 1;
}
else
{
if (calculate(tab, pointer))
printf("%.2f", *pointer);
else {
printf("Incorrect input");
return 1;
}
}
return 0;
}
【问题讨论】:
-
用
if (tab[i] == '\n')替换if (*(tab + i) == 10)会更清楚。使用下标是明智的;使用*(ptr + idx)不是;换行使用'\n',空格使用' '比使用10和32更明智。还要考虑<ctype.h>和isdigit()等的优点。 -
你可能可以使用递归;我不相信这会使代码受益。你支持括号吗?你应该吗?
-
我需要使用指针,我现在需要使用递归,我已经尝试过实现它,但对我来说很难。从一开始就应该知道使用它..
-
for (; i <= strlen(expr); i++) { -
指针符号将归结为教师对“使用指针”的定义——使用
ptr[idx]是使用指针(其中一个术语必须是订阅才能使用的指针),但是它使用指针比使用*(ptr + idx)更具可读性。至于递归,您需要决定递归的内容。例如,如果您支持括号,则可能有代码在遇到左括号(左括号,又名()时对表达式进行递归,并在遇到平衡的右括号(又名))时停止递归。如果遇到另一个(,请递归。