0

文字配列として取得された式を評価し、式の結果を返そうとしています。

例えば:

char *myeExpression []= "(1+2) * 3"

結果 9 を返す必要があります。

これが私のコードです:

struct node {
double element;
struct node *next;
} *head;

void push(int c);      // function to push a node onto the stack
int pop();             // function to pop the top node of stack
void traceStack();      // function to //print the stack values

 int prece(char j)
{
if(j=='*'||j=='/')
{
   j=3;
}
else
{
    if(j=='+'||j=='-')
    {
       j=2;
    }
    else
    {
       j=1;
    }
}
return j;
}


 int evaluate(char *  a) {
int i = 0, j = 0,k,l,a1,b1;   // indexes to keep track of current position
char *exp = (char *)malloc(sizeof(char)*100);
double res = 0;

char stack[5];
char tmp;
head = NULL;

//  converting an infix to a postfix

for(i=0;i<10;i++)
{
    a1=prece(a[i]);
    b1=prece(stack[k]);
    if(a1<=b1)
    {
        exp[l]=a[i];
        l++;
    }
    else
    {
        stack[k]=a[i];
        k++;

    }
}
for(i=k;i>0;i--)
{
    exp[l]=stack[i];
    l++;
}



//end
i=0;
j=0;
k=0;


while( (tmp=exp[i++]) != '\0') {    // repeat till the last null terminator
    // if the char is operand, pust it into the stack
    if(tmp >= '0' && tmp <= '9') {
        int no = tmp - '0';
        push(no);
        continue;
    }

    if(tmp == '+') {
        int no1 = pop();
        int no2 = pop();
        push(no1 + no2);
    } else if (tmp == '-') {
        int no1 = pop();
        int no2 = pop();
        push(no1 - no2);
    } else if (tmp == '*') {
        int no1 = pop();
        int no2 = pop();
        push(no1 * no2);
    } else if (tmp == '/') {
        int no1 = pop();
        int no2 = pop();
        push(no1 / no2);
    }
}
return pop();

}

void push(int c) {
if(head == NULL) {
    head = malloc(sizeof(struct node));
    head->element = c;
    head->next = NULL;
} else {
    struct node *tNode;
    tNode = malloc(sizeof(struct node));
    tNode->element = c;
    tNode->next = head;
    head = tNode;
}
}

 int pop() {
struct node *tNode;
tNode = head;
head = head->next;
return tNode->element;
}

中置式の評価は行われますが、完全ではありません。9 ではなく 3 という間違った結果が得られます。

4

2 に答える 2

1

コードは、空白を明示的に無視したり、処理したりしません。これがトラブルの原因のひとつですか?コンパイラは次のことを示します。

  • k初期化されていません
  • l初期化されていません

これらの初期化されていない値は、配列へのインデックスとして使用されます。for (i = 0; i < 10; i++)実際の長さに関係なく、文字列をスキャンするために使用します。これは幸せのレシピではありません。

括弧には優先順位1(低)が与えられます。通常、それらには高い優先順位が与えられます。中置から接頭辞に変換するときに、それらがどのように処理されるかを決定する必要があります。

スタックに何かをプッシュする前の優先順位と物事を比較stack[k]します。一般に、プレフィックスからプレフィックスへの変換は信頼できないようです。先に進む前に、それを正しくすることに集中する必要があります。

デバッガーでコードを実行し、コードを1行ずつステップ実行して何が問題になっているのかを確認するか、デバッグ用のprintステートメントを追加する方法を学ぶ必要があります(これが私が通常行う方法です)。

于 2013-01-12T16:46:56.920 に答える
0

lex と yacc は、lexer と parser を構築する際の困難の多くを取り除くので、学ぶことができます。「calc」は、単純な算術式を計算できる標準的な例です。たとえば、ここで見つけることができます。

于 2013-01-12T17:46:14.847 に答える