我必须创建一个以中缀表示法表达的代码,并输出正确的答案。
示例输入如下:
3
2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
3.8120 / 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
第一个输入是一个整数,表示将跟随多少个表达式。
为了解决这个问题,我创建了一个函数 result(),它接受一个包含表达式的字符串。此函数仅适用于循环的第一次迭代。
从这个错误中,我怀疑是否有一些关于我如何接受输入的东西,所以我在我的main函数中放置了一个print语句,看看我是否从STDIN得到了正确的输入:
int main(void) {
int num; //get num of expressions
scanf("%d", &num);
getchar(); //get newline
char exp[MAX];
//gets the whole string of input
for(int a = 0; a < num; a++) {
fgets(exp, MAX, stdin);
exp[strlen(exp)-1] = 0;
printf("STDIN: %s\n", exp);
//double ans = result(exp);
memset(exp, 0, MAX);
//printf("%0.4lf\n\n", ans);
}
}
这是我的输出:
STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
STDIN: 1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
STDIN: 3.8120 / 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
所以,从这里开始,我知道STDIN确实得到了正确的输入。接下来,在我的结果函数中,我放置了一个print语句,用于检查输入到函数中的字符串的值。现在,如果我取消注释main中调用函数结果的行,并输入相同的输入,我会得到不同的输出。
STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
FUNCTION: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
STDIN: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
FUNCTION: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
STDIN: 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
FUNCTION: 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
为什么会这样?即使我删除函数中的print语句,也会发生此错误。只要我调用函数 result()
,就会发生这种情况当我调用函数时从STDIN输入:
STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
STDIN: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
STDIN: 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
我怀疑它与空白有关,但我无法弄清楚该错误会发生在哪里?我已经处理好换行了吗?
完整代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MAX 100000
struct Stack {
int data[MAX];
int top;
};
typedef struct Stack Stack;
double numbers[MAX]; //stack for numbers
int numTop;
void Initialize(Stack *S) {
S->top = -1;
memset(S->data, 0, MAX);
}
void initNumbers() {
numTop = -1;
memset(numbers, 0, MAX);
}
char peek(Stack *S) {
return S->data[S->top];
}
void push(Stack *S, char c) {
S->top++;
S->data[S->top] = c;
}
char pop(Stack *S) {
char value = S->data[S->top];
S->top--;
return value;
}
int isEmpty(Stack *S) {
if(S->top == -1) {
return 1; //empty
} else {
return 0;
}
}
int isDigit(char c) {
if(c >= '0' && c <= '9' || c == '.') {
return 1;
} else {
return 0;
}
}
int isOperation(char c) {
if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
return 1;
} else {
return 0;
}
}
double ConvertTodouble(char exp[], int a, int size) {
char temp[MAX];
memset(temp, 0, MAX);
for(int i = 0; i < size; i++) {
temp[i] = exp[a];
a++;
}
return atof(temp);
}
void pushNum(double num) { //for num array
numTop++;
numbers[numTop] = num;
}
double popNum() {
double result = numbers[numTop];
numTop--;
return result;
}
double evaluate(double a, double b, char op) {
if(op == '+') {
return a + b;
} else if(op == '-') {
return a - b;
} else if(op == '*') {
return a * b;
} else if(op == '/') {
return a / b;
} else if(op == '^') {
return pow(a, b);
}
}
int weight(char c) {
switch(c) {
case '+':
case '-': return 1;
break;
case '*':
case '/': return 2;
break;
case '^': return 3;
break;
}
}
//if isp > icp, pop (returns 1)
//this returns 1 if isp > icp (left associative)
//returns 1, we pop
int higherPrecedence(char instack, char incoming) {
int isp = weight(instack);
int icp = weight(incoming);
if((isp == icp) && instack == '^') {
return 0;
} else if((isp == icp) && instack != '^') {
return 1;
}
if(isp > icp) {
return 1;
} else {
return 0;
}
}
double result(char exp[]) {
Stack S; //stack for operations (+,-,*,/,^)
double ans = 0;
Initialize(&S);
initNumbers();
int len = strlen(exp);
int flag = 0;
for(int i = 0; i < len; i++) {
if(exp[i] == ' ') {
getchar();
} else if(isDigit(exp[i])) {
//gets number from char array and converts to double
flag = i; //flag determines how many spaces to move pointer later
for(int a = i; a < len; a++) {
if(exp[a] == ' ') {
break;
} else {
flag++;
}
}
int size = flag - i;
double number = ConvertTodouble(exp, i, size);
pushNum(number);
i = flag - 1; //update the index so we won't repeat operation
} else if (exp[i] == '(') {
push(&S, '(');
} else if(isOperation(exp[i])) {
while(!isEmpty(&S) && peek(&S) != '(' && higherPrecedence(peek(&S), exp[i])) {
char op = pop(&S);
double b = popNum();
double a = popNum();
ans = evaluate(a,b,op);
pushNum(ans);
}
push(&S, exp[i]);
} else if(exp[i] == ')') {
while(!isEmpty(&S) && peek(&S) != '(') {
char op = pop(&S);
double b = popNum();
double a = popNum();
ans = evaluate(a,b,op);
pushNum(ans);
}
char throw = pop(&S); //this gets the '('
}
}
while(!isEmpty(&S)) {
char op = pop(&S);
double b = popNum();
double a = popNum();
ans = evaluate(a,b,op);
pushNum(ans);
if(numTop == 0) {
break;
}
}
return ans;
}
int main(void) {
int num; //get num of expressions
scanf("%d", &num);
getchar(); //get newline
char exp[MAX];
//gets the whole string of input
for(int a = 0; a < num; a++) {
printf("Before: %s\n", exp);
fgets(exp, MAX, stdin);
exp[strlen(exp)-1] = 0;
printf("STDIN: %s\n", exp);
double ans = result(exp);
memset(exp, 0, MAX);
//printf("%0.4lf\n\n", ans);
}
}
答案 0 :(得分:1)
嗯,我想我发现了这个错误。
你可以看到这里发生了什么
// fixed header
$(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 80) {
$("body").addClass('fixed');
} else {
$("body").removeClass("fixed");
}
});
});
12个西卡特失踪了。
检查上一行
1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
^
|
you got it from here.
有12个空格。
所以这就是导致错误的原因。
2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
x x x x x x x x x x x x
更改代码的逻辑。希望这会有所帮助。