0

oh, forgive me but i found the problem. i replaced operators on line 74 with operators2 and it works fine now.

0

Hey thecoolman5, don't worry if my code-block doesn't make sense yet, just go back and look at it once in a while. It's a good beginning to your question about "what if the user doesn't type in spaces?" but isn't necessary at this point. And what you'd do with it, as far as solving the equation, is similar to what you're already doing. With the added benefit that you've already determined whether each item is a number, a variable, or an operator, so you can detect whether the user typed in something that doesn't make sense.

Let me know if you get stuck on something else.

0

Ok. I just need to know how to operators, operators2, and operators3 to detect '^'. also I need it to be able to detect any other variable than just x.

```
If(n1 == string)
{
// the rest of the code
```

*Edited
by thecoolman5*: n/a

0

Detecting '^' is no different from checking for any other operator. The problem you're more likely to be running into now is implicit operator precedence. In the simplest case, if the user types in "3 + 5 * 2 = x", you need to make sure that you're doing the "5 * 2" part before the "3 +" part. Same for '^', that will have to come before "*/" or "+-".

As far as detecting more variables than "just x" ... if you want the user to be able to use "y" instead, then it might be as simple as "if it's not a number or an operator, then replace it with x" and continue as you do now. If you want to remember that it used to be y, save it in a separate variable, and replace it when you print out the result:

```
string actual_var = "";
if ((strtream(n2) >> n2_val).fail()) {
actual_var = n2;
n2 = "x";
}
// do rest of equation solving here
if (actual_var != "") {
cout << actual_var << " = " << answer;
}
else {
cout << "answer = " << answer;
}
```

If instead you want the user to be able to input something like "y = 3 * x + 5", that's a whole other level of code management, and you're not approaching the problem in a sufficiently scalable manner -- what are you going to do when you're ready to read something like "z = x ^ 2 + y ^ 2 - 2 * x * y"? If you keep going the way you have been, you'll have hundreds, or possibly thousands of lines of almost-unmaintainable code. You really need to start appreciating a topic called "data structures" and also working with your equations at a more abstract level.

0

Yeah. I know what you mean. I just know too little of the c++ language. Plus, I taught it to myself. Back on the 1st page, you said "recursive descent parser". Do you happen to have a recursive descent parser code? Or do you think you could post a data structure code snippet that I might understand? Thanks.

0

No, I don't have anything already written, I'm pretty sure I made that point as well. :) As far as data structures, I'd recommend grabbing a book. I bet there's a decent "Data Structures in C++" book on the shelves of your local book store, or they'd be able to point you to another store to try.

Rather than trying to come up with code that you can understand, which solves your problem, I'd prefer that you actually take a bit of a break (if you need) and learn more about programming in general ... then when you go back to reading specifically about "recursive descent parsers", it'll make more sense to you, and you'll have a much better idea how to approach the problem code-wise.

Not that it helps much now, but you can think of your equations in a hierarchical sense:

+ an equation is made up of expressions on either side of an '=' sign (*)

+ an expression is a sequence: operand, operator, operand, ..., operand.

+++ an exception to the above is the unary "negation" operator which doesn't need a preceding operand.

+ operators include +, -, *, /, ^ (others too, i bet)

+ operands can be numeric constants, variables, or other expressions (**)

(*) in fact, you can think of the entire equation as a single expression, where the "=" (along with "<", ">", etc.) is a "relational operator" -- one that returns true or false instead of a numeric answer

(**) especially useful for incorporating "()" ... "(" denotes the start of a sub-expression, which can be treated exactly like any other expression. also now that an expression can contain sub-expressions, which can in turn contain sub-sub-expressions, you can see where the "recursive" part comes in. The "descent" part comes from working your way through a branching "tree" structure of operands and operators, accumulating partial results in the correct order -- in computer science, trees are represented with the "root" at the top, and the branches growing downward, probably just because its easier to deal with on paper that way. A data structure for a point in the tree might look something like:

```
struct rdp_node {
bool is_operator; // tells whether the "op" or "value" is relevant
Operator op;
Value val;
struct rdp_node *left_operand;
struct rdp_node *right_operand;
};
typedef struct rdp_node RDPNode; // Now you can say something like RDPNode *ptr = new RDPNode();
```

I'm not defining the Operator or Value class/structure yet, the point here is simply that you can have a data structure that can "point to" other objects of the same type, in this case left and right sub-expressions, which might be other "operator nodes", or might be "value nodes".

I'm also not writing full-up tree code for you. Functions you would need, in order to make the data structure useful, include "add a node into the tree", "compute the value of this node, taking into account its sub-nodes", "print the expression represented by this tree", "get rid of this tree (and all the nodes in it)", and so on. Of particular interest is "build up a tree from the input expression/equation" which requires no small amount of thought. Try it out on paper -- how would you represent "3 + 2 * 5" using the RDPNode structure above? (Hint: try drawing one node as a box with four rows, the bottom row divided into two columns, one will start an arrow pointing down and to the left, the other will start an arrow pointing down and to the right, each to another box). What goes at the root/top of the tree? What are the "leaf nodes" (those that don't point to any sub-expressions)?)

0

So about the book. I have c++ for dummies and when I came up with the idea to make a variable equation solver, I looked around my house for about an hour and I still can't find it.

0

various input on books here: http://stackoverflow.com/questions/366317/good-data-structures-text-book. I can vouch for Aho, Hopcroft, Ullman -- but like other commenters, it was my college text over 20 years ago. And definitely -not- C++-specific. The good news is, data structures are virtually identical in every programming language, so the primary purpose is to understand the structures, how and when to use them, and what's involved in a complete and correct implementation, regardless of the programming language of choice. Also from the top of this C++ forum: http://www.daniweb.com/software-development/cpp/threads/70096

0

Hey, Im wondering if you know how to detect a char in a string.

0

You should really start a new thread for new questions since this is a really old thread.

To find a char in a string you can use the find() member of the string class and get the index of it.

example:

```
#include <iostream>
#include <string>
using namespace std;
int main()
{
string eqn = "x + 2 + 2 = 3";
int pos = -1;
char toFind = '+';
do //this loop will find all occurrences of the char to you want to find
{
pos = eqn.find(toFind, pos+1);
if( pos != -1 ) //if the char was found
cout << toFind << " was found at " << pos << endl;
}while( pos != -1 ); //end loop if char wasn't found
return 0;
}
```

*Edited
by sfuo*: Changed to find all positions of the char

0

i am also wondering how to retrieve all the numbers in an equation.

```
cin >> equation //equation is 1-3/7*3
cout << numbers << endl; //output is 1,3,7, and 3
```

0

Here is something I threw together pretty quick.

This breaks down the input into separate strings of numbers and operators.

You can use atoi() (string to int) to convert the number of string type to an integer.

This is pretty basic so you will want to add to it if you want variables and other things.

```
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> eqnParts;
string eqn, part = "";
cout << "Please input your equation: ";
getline(cin, eqn);
for( unsigned int i = 0; i < eqn.length(); i++ )
{
if( eqn[i] == '+' || eqn[i] == '-' || eqn[i] == '*' || eqn[i] == '/' )
{
eqnParts.push_back(part);
part = eqn[i];
eqnParts.push_back(part);
part = "";
}
else
{
part += eqn[i];
if( i == eqn.length()-1 )
eqnParts.push_back(part);
}
}
for( unsigned int i = 0; i < eqnParts.size(); i++ )
cout << eqnParts[i] << endl;
return 0;
}
```

0

here, take a look at my new thread. its related to this one. http://www.daniweb.com/software-development/cpp/threads/370974

0

ok guys. I finally finished a full working calculator that can handle parantehsis, order of operations, and unlimited operators.

```
#include<iostream>
#include<string>
#include<sstream>
#include<windows.h>
#include<conio.h>
#include<ctime>
using namespace std;
int main ()
{
cout << "No variables." << endl;
cout << "Type in cls to clear the screen, and type exit to exit." << endl;
SetConsoleTitle("Calculator");
for(;;)
{
re:
string equation = "";
string equation2 = "";
string equation3 = "";
string equation4 = "";
string equation5 = "";
int non_digit5 = 0;
int non_digit2 = -1;
int non_digit6 = 0;
int c = 0;
int i = 0;
float n1 = 0;
string operators = "";
float n2 = 0;
cin >> equation;
DWORD ticks = GetTickCount();
if(equation == "exit")
{
return 0;
}
if(equation == "cls")
{
system("cls");
goto re;
}
while(true)
{
c = equation.find('(', c);
if(c == -1)
{
break;
}
//PARENTHESIS SOLVING CODE
do
{
non_digit2 = equation.find('(', non_digit2+1);
if(non_digit2 == -1)
{
break;
}
non_digit5 = non_digit2;
}while(non_digit2 != -1);
non_digit5 = non_digit5 + 1;
int non_digit3 = 0;
//DOUBLE PARANTHESIS EQUATIONS
equation4 = equation.substr(non_digit5, 999999999);
int l = equation.length();
int l1 = equation4.length();
non_digit3 = equation4.find(")", non_digit3+1);
l1 = l1 - non_digit3;
l = l - l1;
non_digit3 = l;
equation3 = equation.substr(non_digit3+1, 999999999);
equation2 = equation.substr(non_digit5, non_digit3);
do
{
non_digit2 = equation2.find(')', non_digit2+1);
if(non_digit2 == -1)
{
break;
}
non_digit6 = non_digit2;
}while(non_digit2 != -1);
equation2 = equation2.substr(0, non_digit6);
equation = equation.substr(0, non_digit5-1);
n1 = 0;
operators = "";
n2 = 0;
int non_digit = equation2.find_first_not_of("12345677890.");
string part = equation2.substr(0, non_digit);
stringstream(part) >> n1;
operators = equation2[non_digit];
equation2 = equation2.substr(non_digit + 1);
while(true)
{
n2 = 0;
non_digit = equation2.find_first_not_of("1234567890.");
part = equation2.substr (0, non_digit);
stringstream(part) >> n2;
if(int(non_digit) == 0)
{
string part = equation2.substr (0, non_digit+3);
stringstream(part) >> n2;
equation2 = equation2.substr(non_digit + 1);
}
if(operators == "+")
{
n1 = n1 + n2;
}
if(operators == "-")
{
n1 = n1 - n2;
}
if(operators == "*")
{
n1 = n1 * n2;
}
if(operators == "/")
{
n1 = n1 / n2;
}
if(non_digit == -1)
{
break;
}
non_digit = equation2.find_first_not_of("0123456789.");
operators = equation2[non_digit];
equation2 = equation2.substr(non_digit + 1);
}
stringstream out;
out << n1;
equation = equation + out.str();
equation = equation + equation3;
}
//ORDER OF OPERATIONS
while(true)
{
c = equation.find_first_not_of("1234567890.-+");
if(c == -1)
{
break;
}
equation2 = "";
equation3 = "";
equation4 = "";
operators = "";
float n1 = 0;
float n2 = 0;
float n3 = 0;
int non_digit = equation.find_first_not_of("1234567890.-+");
operators = equation[non_digit];
equation2 = equation.substr(non_digit+1, 999999999);
stringstream(equation2) >> n1;
equation3 = equation.substr(0,non_digit);
reverse(equation3.begin(), equation3.end());
//BEGIN FIXING REVERSED EQUATION
non_digit = equation3.find_first_not_of("1234567890.");
if(non_digit == -1)
{
reverse(equation3.begin(), equation3.end());
stringstream(equation3) >> n2;
}
else
{
equation5 = equation3.substr(0, non_digit);
reverse(equation5.begin(), equation5.end());
stringstream(equation5) >> n2;
}
stringstream out;
out << n2;
equation4 = equation4 + out.str();
equation4 = equation4 + operators;
stringstream out1;
out1 << n1;
equation4 = equation4 + out1.str();
//END OF FIND OPERATOR
int l = equation4.length();
non_digit = equation.find(equation4);
equation2 = equation.substr(0, non_digit);
equation4 = equation.substr(non_digit+l, 999999999);
if(operators == "/")
{
n3 = n2 / n1;
}
if(operators == "*")
{
n3 = n2 * n1;
}
stringstream out2;
out2 << n3;
equation2 = equation2 + out2.str();
equation2 = equation2 + equation4;
equation = equation2;
}
//START FIXED EQUATION SOLVING
n1 = 0;
operators = "";
n2 = 0;
size_t non_digit = equation.find_first_not_of("12345677890.");
string part = equation.substr (0, non_digit);
stringstream(part) >> n1;
operators = equation[non_digit];
equation = equation.substr(non_digit + 1);
while (true)
{
n2 = 0;
size_t non_digit = equation.find_first_not_of("1234567890.");
string part = equation.substr (0, non_digit);
stringstream(part) >> n2;
if(int(non_digit) == 0)
{
string part = equation.substr (0, non_digit+3);
stringstream(part) >> n2;
equation = equation.substr(non_digit + 1);
}
if(operators == "+")
{
n1 = n1 + n2;
}
if(operators == "-")
{
n1 = n1 - n2;
}
if(operators == "*")
{
n1 = n1 * n2;
}
if(operators == "/")
{
n1 = n1 / n2;
}
if (int(non_digit) == -1)
{
break;
}
non_digit = equation.find_first_not_of("0123456789.");
operators = equation[non_digit];
equation = equation.substr(non_digit + 1);
}
cout << "Speed of calculation: " << GetTickCount() - ticks << " milliseconds." << endl;
cout << "Result : " << n1 << endl;
system("pause");
goto re;
}
}
```

Please dont edit the code in any way. This calculator is very special to me. its the first advanced program that i have coded. Thanks for all your help.

0

Let me just warn you that I am a beginner in early C + +. So I searched recursive descent parser and I know idea how to put this into code.

This question has already been answered. Start a new discussion instead.

Recommended Topics

Hey Guys,

So I have a JTextfield in the cells of 1 of the columns in my JTable

I want to allow only numbers and up to one dot/period. Doesant ...

vb.Net - Regular Expression Tester

Every now and then I find another use for a regular expression. For those not familiar with regular expressions, they can be as cryptic to ...