简体   繁体   中英

Working with mathematical operations received as input

Let's say I'd like to receive two mathematical operations from a user (eg + - % ) and calculate numbers accordingly. Let's also say I can use one if/else statement to determine precedence (and that all operations have different precedences).

I have several ideas in mind for implementation, and would like feedback regarding which is considered "better" coding (clearer, more efficient, etc.).

  1. I could do something like this:

     if (firstOperator >= secondOperator){ switch (firstOperator){ case '+': switch (secondOperator) // insert all 6 possible cases case '-': switch (secondOperator) // insert all 5 possible cases ... ... } else{ // same idea as above } 
  2. Or I could simply hard-code all options by creating one switch for every option of firstOperation , and nest a second switch in each of those cases for all possible secondOperation .

The two approaches are different, and I have one or two more. I would have thought that the first is more "correct" and elegant, but it actually results in more lines of code than the "brute-force" all-out second option.

I would love to hear any input regarding this kind of coding.

Note: I'm talking about only very basic C programming (ie without using other data structures like stacks, etc. Just the basic if/else , switch , loops , etc.

Here's how I would have done it, but it depends on your first and second operations being independently handled (which I think should be possible if what you are doing is an expression evaluator). In my example, I assume there is a queue holding the arguments that were parsed in the order they were parsed.

if (firstOperator >= secondOperator) {
    handle(firstOperator);
    handle(secondOperator);
} else {
    // Assuming something like 1 + 2 * 3, with 1 2 3 in the queue:
    //
    // tmp = dequeueArg() makes the queue: 2 3
    // handle('*')        makes the queue: 6
    // pushFront(tmp)     makes the queue: 1 6
    // handle('+')        makes the queue: 7
    //
    int tmp = dequeueArg();
    handle(secondOperator);
    pushFront(tmp);
    handle(firstOperator);
}

void handle(Op operator)
{
    int x = dequeueArg();
    int y = dequeueArg();

    switch (operator) {
        case '+': pushFront(x+y); break;
        case '-': pushFront(x-y); break;
        case '*': pushFront(x*y); break;
        case '/': pushFront(x/y); break; // Maybe check for 0
        case '%': pushFront(x%y); break; // Maybe check for 0
        case '&': pushFront(x&y); break;
        etc...
    }
}

What I wrote here probably will not work as a general infix parser with precedence. It's more an example of how to not use O(N^2) nested case statements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM