'How Can I convert infix expression containing ++ or -- to a normal infix expression

Basically, I'm trying to get rid of ++ or -- from an infix expression by incrementing the value that's applied to it, but the code gives a weird output. I also used a shifting function to delete the ++ or --.

for example:

-infix before: 1++-4/5

-infix after: 2-4/5

-my program outputs: ,-4/5/5

Here's my code(contains only functions relevant to the problem):

void shift(int i, int j, char expression[])
{
    for (int k = i + 1; k < strlen(expression); k++)
    {
        expression[j++] = expression[k];
    }
}
void unary_to_normal(char expression[])
{
    int j = 0;
    for (int i = 1; i < strlen(expression); i++)
    {
        // for ++
        if (expression[j] == expression[i] && expression[j] == '+')
        {   //char to int
            int integer = (expression[j] - '0') + 1;
            //int to char
            expression[j - 1] = integer + '0';
            shift(i, j, expression);
        }
        // for --
        if (expression[j] == expression[i] && expression[j] == '-')
        {   //converting char to int
            int integer = (expression[j] - '0') + 1;
            //int to char
            expression[j - 1] = integer + '0';
            shift(i, j, expression);
        }
        j++;
    }
}


Solution 1:[1]

I get the general idea but I'm not sure I completely understand what's going on in your code. From what you posted I believe I see a few issues:

major: if code blocks

In the code inside the if blocks:

            int integer = (expression[j] - '0') + 1;
            //int to char
            expression[j - 1] = integer + '0';
            shift(i, j, expression);

For that code to be reached, expression[j] should be '+' or '-'. What exactly are you trying to achieve with the integer declaration? That'll result in either -4 or -2 (ascii table). In turn, the operand over which it was acting (expression[j - 1]) will be converted into , (44 integer) or . (46 integer).

Based on your initial example (1++-4/5) I'd expect you wanted to do something like the following instead:

            expression[j - 1]++;
            shift(i, j, expression);

Mind there'll still be pitfalls with that code. It won't cover the "overflow" from 9 to 10.

Given the initial code I'm assuming you were ok with that. If that's not the case you'll need to solve for these issues as well.

major: for -- adding instead of subtracting

In the for -- if block you should be subtracting 1 instead of adding. Considering the previous item it should be something like:

            expression[j - 1]--;
            shift(i, j, expression);

Mind the "underflow" in case the -- operand is 0 (or any number that ends in 0) won't be covered.

major: shift function loop

The strlen function returns the number of characters in a null-terminated string. It doesn't include the null-terminator itself. That's why you're getting the /5/5 repetition at the end of the final string.

One way of fixing it would be making the for loop run until k <= strlen(expression). That way you'd be copying the null-terminator as well.

unsure: -- and ++ operators logic

This might not be an issue to the logic you're trying to implement but there's a very important difference to where these operators are located in C. If they prepend the operand (e.g. ++x), the operator is first applied and, only after that, the expression is evaluated. The order is reversed if the operator is inserted after the operand (e.g. x++).

For instance, the following expressions evaluate to different values:

  • int x = 1; x++-4;, in C, will result in -3
  • int x = 1; ++x-4;, in C, will result in -2

If that's irrelevant to your expression parser you can safely ignore this section.

minor: micro-optimizing the for loop in the unary_to_normal function

Instead of handling the j variable manually you can manage it in the for loop alongside i. The following is perfectly valid:

for (int i = 1, j = 0; i < strlen(expression); i++, j++)

Unless you have a reason not to increase j in every loop iteration you should consider having the for loop handle it instead of doing it manually. That's less likely to lead to errors and it makes your intention clearer to other readers.


A working version (considering the caveats that were previously mentioned) would look something like the following:

void shift(int i, int j, char expression[])
{
    for (int k = i + 1; k <= strlen(expression); k++)
    {
        expression[j++] = expression[k];
    }
}
void unary_to_normal(char expression[])
{
    for (int i = 1, j = 0; i < strlen(expression); i++, j++)
    {
        // for ++
        if (expression[j] == expression[i] && expression[j] == '+')
        {
            expression[j - 1]++;
            shift(i, j, expression);
        }
        // for --
        if (expression[j] == expression[i] && expression[j] == '-')
        {
            expression[j - 1]--;
            shift(i, j, expression);
        }
    }
}

For these functions, an input expression 1++-4/5 is converted to 2-4/5. 1---4/5 is converted to 0-4/5.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Wilk Maia