2

A example of what I want to do:

User puts numbers into a list on a GUI that looks like this

 | L1 | L2 | l3 |
 ----------------
 | 3  |  6 |    |
 | 5  |  3 |    |
  ...

He writes in a text area an equation like this; L1+L2[STO>]L3 and hits calculate and it updates the list to this

 | L1 | L2 | L3 |
 ----------------
 | 3  |  6 |  9 |
 | 5  |  3 |  8 |

In row one, 3 + 6 = 9 so the corresponding row of the numbers match the box, the corresponding row in list 3 is updated. We selected list one by typing L1, and we used a store opperator ([STO>]) to store the numbers into list 3. This is not new, I found this idea on ti-83, ti-84, and stat programs which use this.

This seemed simple at first; I could solve it knowing the equation beforehand with a simple algorithm. For example, with an equation such as L1+L2[STO>]L3 I could loop through the 2d array using the index value and store the numbers into an array to process the numbers from there. To illustrate I wrote a simple code snippet

for(int i = 0; i <= 100; i++) {
    data[i][0] + data[i][1] = data[i][2];
}
//Then update GUI

//So the data array was how I store user data from the gui, 
//index 1 grabs the value from the row and index 2 is the corresponding list item.

The problem:

I don't know how to proceed when I don't know the user defined equation. The user should be able to put in anything that you could put into a calculator. For example, valid inputs could also be L1*3455[STO>]L2, L1/L2[STO>]L3 ect.

3

You have two options.

Option 1: Write your own parser. Start by reading up on "parse tree" and "recursive descent parser". So, the user enters the expression as text in whatever syntax you decide, you parse the text, you build an expression tree, some of the nodes in the tree will be line identifiers, some will be constants, some will be operators, you substitute identifiers with values, run the tree to evaluate the operators, you receive a result. It is not easy, but it is not rocket science, either.

Option 2: Embed a javascript engine like Rhino into your java application. Again, the user enters an expression as text in javascript syntax, the javascript engine parses it, you supply the engine with a value for each variable, you run the engine to evaluate the expression, you obtain a result. It is not easy either, but you are far more likely to find tutorials that will do most of the work for you. You don't get to choose the syntax of the expressions, but if I compare javascript syntax with the odd thing you described above, I think it's a good thing that you don't get to choose the syntax.

  • Absolutely #1. In fact, if you edit and remove #2, I will up-vote it immediately. "Never install an external plugin when you can write your own in the same amount of time." Plugins often require upgrades, plugins are often less customizable. But most of all, plugins don't teach us how to think and solve problems. A wise old Asian philosopher once said: "a man who installs 10 plugins solves 10 needs now, but a man who writes his own solves 9 now and 100 later". – John Doe Dec 3 '15 at 1:35
  • 1
    @JohnDoe all this is very true, but it does not change the fact that #2 is an option. An upvote stands for "this answer is useful", and my answer does not become any more useful by omitting an option. – Mike Nakis Dec 3 '15 at 1:39
  • 1
    Ok, fair enough, I up-voted it. One good paragraph can make up for a thousand bad ones. I think an old Asian philosopher said that, too. – John Doe Dec 3 '15 at 1:42
  • Also, check this out, in case it represents an acceptable quick and dirty solution for you: stackoverflow.com/a/7143460/773113 – Mike Nakis Dec 3 '15 at 2:16
  • 1
    Awesome! I will keep that for a plan b, if I can't write a parser before my deadline that is. – user275564 Dec 3 '15 at 2:59
1

I decided to solve this problem by taking the equation and evaluating it to PostFix then evaluating the postFix Expression. This is my C++ implementation.

string convertToPostfix(string& infix)
{
std::stack<char> stack;
string output;

infix.erase(std::remove(infix.begin(), infix.end(), ' '), infix.end());

for (size_t i = 0; i < infix.size(); i++) {
    if (isdigit(infix[i])) {
        if (i >= 1 && !(isdigit(infix[i - 1])))
            output.push_back(' ');

        output.push_back(infix[i]);
    }
    else if (infix[i] == '(') {
        stack.push(infix[i]);
    }
    else if (isOperator(infix[i])) {

        while ((!stack.empty()) && stack.top() != '(') {
            if (precedence(stack.top(), infix[i])) {
                output.push_back(' ');
                output.push_back(stack.top());
                stack.pop();
            }
            else {
                break;
            }
        }

        stack.push(infix[i]);
    }
    else if (infix[i] == ')') {
        while (!stack.empty() && (stack.top() != '(')) {
            output.push_back(' ');
            output.push_back(stack.top());
            stack.pop();
        }

        if (!stack.empty()) {
            stack.pop();
        }
    }
}
while (!stack.empty()) {
    output.push_back(' ');
    output.push_back(stack.top());
    stack.pop();
}

return output;
}

int evaluatePostFix(string postfix) {
stack<int> resultStack;

int length = postfix.length();

int accumlatedMultipleDigits = 0;

for (int i = 0; i < length; i++) {

    if (isOperator(postfix[i])) {
        int first = resultStack.top();
        resultStack.pop();
        int second = resultStack.top();
        resultStack.pop();

        int result = applyOperator(first, second, postfix[i]);
        resultStack.push(result);
    }
    else if ((postfix[i] >= '0') || (postfix[i] <= '9') && !postfix[i] == ' ') {

        int postfixValue = postfix[i] - 48;

        if (i >= 1) {
            if (postfix[i - 1] == ' ') {

                /* FIRST VALUE */

                accumlatedMultipleDigits = postfixValue;
            }
            else {
                //add new value to end of accumlatedMultipleDigits
                accumlatedMultipleDigits = accumlatedMultipleDigits * 10 + postfixValue;
            }
        }
        else { /*It is 0 or less index of string, means must be value */
            accumlatedMultipleDigits = postfixValue;
        }

        if (postfix.length() > i) {

            if (postfix[i + 1] == ' ') {/* END OF VALUE*/
                resultStack.push(accumlatedMultipleDigits);
                accumlatedMultipleDigits = 0;
            }
        }

    }
}
return resultStack.top();
}

With this we can solve this problem line by line and store into the correct corresponding row.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.