-1

This is a follow up to This question. at this point I want the program to identify the variables by itself and then ask the user for variable values .so instead of looking like:

Enter an Expression: 

ADD(DIV(SIN(FACT(X1)),CEIL(TAN(MUL(1.5,FIB(X2))))),GCD(Y,10))     

Enter Variables: X1,X2,Y    
Enter values for X1, X2 and Y by this order(separate the values by space): 3 4 2    
The Result is: 1.94    

the program should function like :

Enter an Expression: 

ADD(DIV(SIN(FACT(X1)),CEIL(TAN(MUL(1.5,FIB(X2))))),GCD(Y,10))     

your variables are : X1,X2,Y    

now Enter values for X1, X2 and Y by this order(separate the values by space): 3 4 2    
The Result is: 1.94    

so the user no longer needs to tell the machine what the variables are. how can achieve this?

I have checked This question but it's quite different from what I need and also it's in python

UPDATE: specifically I want to iterate shunting yard algorithm so it can find the variables. I've put a link for the parser code below http://paste.ubuntu.com/9999494/

Vicarious
  • 131
  • 18

2 Answers2

0

You should store the names of all your functions, and then look for all arguments which are neither functions nor numbers.

So when you scan the input ADD(X, DIV(3, Y)), it should detect that ADD and DIV are functions and 3 is a number. This leaves X and Y, which must therefore be variables. Basically, whenever you detect a bracket, you should look for the matching closing bracket, then split the contents of those brackets at the commas and evaluate each part. If a part is neither a number nor a function, it must be a variable.

DennisW
  • 1,057
  • 1
  • 8
  • 17
0

I would suggest the following algorithm:

  1. Split the text into tokens separated by '(', ')' or ','
  2. Search through the tokens filtering out known functions and numbers
  3. Everything remaining is a variable

Here is a possible implementation using Java 8 streams:

List<String> getVariables(String expression, List<String> functions) {
    return Collections.list(new StringTokenizer(expression, "(),")).stream()
        .map(Object::toString)
        .filter(token -> !functions.contains(token))
        .filter(token -> !token.matches("\-?\d+\.?\d*"))
        .collect(Collectors.toList());
}
sprinter
  • 27,148
  • 6
  • 47
  • 78
  • thank you for your answer by the way how can I implement this to shunting yard algorithm from EvalEx that I'm using for parsing ? this is the code http://paste.ubuntu.com/9999494/ – Vicarious Feb 01 '15 at 17:48