显示正确的输出后,打印不需要的输出

时间:2018-07-12 20:27:08

标签: c centos

我想出了一种使用递归将中缀更改为后缀表示法的方法,以测试基本程序(其中不包含预期的部分),我只是打印了要评估的字符串。

示例:如果输入为“ A +(BC)”,则输出将仅为“ A + BC ”->,即 BC (””时,将使用递归将em>打印为单独的操作数。遇到时,它将以递归的方式发送其余字符串并打印元素直到遇到为止-发送包含的遍历的元素数作为返回值。

现在,我对算法感到满意,但是在打印输出后 出现了一些奇怪的东西(这似乎是正确的),请看一下并帮助我:

/*THE INPUT SHOULD HAVE NO MISSING PARENTHESES (IF THERE ARE ANY) */

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int fun(char c[])
{
    int len=strlen(c),i=0;

    while(i!=len)
    {
        if(c[i]=='(')
        {
            char cpy[len-i];
            strcpy(cpy,c+i+1);
            ++i;
            //RECURSIVE FUNCTION WHICH RETURNS THE NO. OF ELEMTS IT HAS TRAVERSED INCLUDING ")"
            i+=fun(cpy);
        }
        if(c[i]==')')
        {
            return 1+i;
        }
        //INSTEAD OF PRINTING, STACK OPERATION MAY BE USED TO GET THE POSTFIX NOTATION
        printf("%c",c[i]);
        ++i;
    }
    return i;
}

int main()
{
    int i=0;
    //EVEN THIS UNDERLYING COMMENTED INPUT CAN BE USED
    //i=fun("(A+B*(C-D/E*(K-R))+M)");  
    i=fun("(((A+B)))");
    printf("\n-------------------\n");
    return 0;
 }

现在使用两个不同的输入(其中一个是注释输入)时引发的错误:

OUTPUT IS IN RED, IT IS THE INTENDED OUTPUT

enter image description here


正在使用的编译器为 gcc(GCC)4.8.5 20150623(Red Hat 4.8.5-28)

2 个答案:

答案 0 :(得分:1)

正如我在comment中所指出的那样,您只需要确保在每次迭代中仅执行循环主体中三段代码之一。这是一种可以在问题中的两个示例表达式上正常运行的改编:

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

static int fun(char c[])
{
    int len = strlen(c), i = 0;

    while (i != len)
    {
        if (c[i] == '(')
        {
            char cpy[len - i];
            strcpy(cpy, c + i + 1);
            ++i;
            i += fun(cpy);
        }
        else if (c[i] == ')')
        {
            return 1 + i;
        }
        else
        {
            printf("%c", c[i]);
            ++i;
        }
    }
    return i;
}

static void evaluate(char *expr)
{
    printf("expression: [%s]\n", expr);
    int i = fun(expr);
    printf("\ni = %d\n-------------------\n", i);
}

int main(void)
{
    evaluate("(((A+B)))");
    evaluate("(A+B*(C-D/E*(K-R))+M)");
    return 0;
}

输出:

expression: [(((A+B)))]
A+B
i = 9
-------------------
expression: [(A+B*(C-D/E*(K-R))+M)]
A+B*C-D/E*K-R+M
i = 21
-------------------

commentinfinite

  

使用((A+B)^C-(D*E)/F)作为输入时,else if子句将跳过^

这不是我在测试时发现的,无论是在上面的代码(向evaluate()添加新调用)还是在下面的代码上。这是代码的紧凑版本,它放弃了字符串的复制,并且也产生了正确的输出。

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

static int fun(char c[])
{
    int i = 0;

    while (c[i] != '\0')
    {
        if (c[i] == '(')
            i += fun(&c[i+1]) + 1;
        else if (c[i] == ')')
            return 1 + i;
        else
        {
            printf("%c", c[i]);
            ++i;
        }
    }
    return i;
}

static void evaluate(char *expr)
{
    printf("expression: %zu [%s]\n", strlen(expr), expr);
    int i = fun(expr);
    printf("\ni = %d\n-------------------\n", i);
}

int main(void)
{
    evaluate("(((A+B)))");
    evaluate("(A+B*(C-D/E*(K-R))+M)");
    evaluate("A+B*(C-D/E*(K-R))+M");
    evaluate("((A+B)^C-(D*E)/F)");
    return 0;
}

输出:

expression: 9 [(((A+B)))]
A+B
i = 9
-------------------
expression: 21 [(A+B*(C-D/E*(K-R))+M)]
A+B*C-D/E*K-R+M
i = 21
-------------------
expression: 19 [A+B*(C-D/E*(K-R))+M]
A+B*C-D/E*K-R+M
i = 19
-------------------
expression: 17 [((A+B)^C-(D*E)/F)]
A+B^C-D*E/F
i = 17
-------------------

插入符未放入表达式((A+B)^C-(D*E)/F)中;它可以正确地处理1、2或3个连续的)(在正确的输入下)。如果输入格式错误,生活可能会变得混乱;面对错误,这不是健壮的代码。但是我相信核心是有效输入的基础,有效输入基本上是任何带有平衡的,可选的嵌套的开括号和闭括号的字符串。

答案 1 :(得分:0)

我发现的问题是,应该是while(i!=len),而不是while(i<len)

在最原始的递归阶段(当在原始字符串中首次遇到时) i 大于 len 时所有返回值都从最深的递归返回,其余实现是正确的。