Math issues...
Alright, I''m writing a console-based program in C++ and I''d like to know whether or not it is possible or not to solve a mathematical expression in string.
I.E. :
...
char expression[50]= {"1","+","2","*","3","/","5"};
predefinedfunctionthatsolvesthatthing(expression);
printf("%i",expression);
...
Also, is there a way to get all of the information inputted by a user when there are spaces in it?
I.E. :
...
scanf("%s",myarray);
printf("Look, why won''t this work...%s",myarray);
...
Okay, if the user puts something like: I AM COOL. It only picks up the "I" character.
Anyway, thanks for any help.
--Ax
P.S. I''m a Win32 programmer...
-Ax
It''s very possible with normal programming skills to parse that expression whether if it''s a console app or not.
If you want to read an entire line instead of a space delimited tokens, try the iostream getline( char array, unsigned int array_size ) routine in I believe ( could be wrong ).
If you want to read an entire line instead of a space delimited tokens, try the iostream getline( char array, unsigned int array_size ) routine in I believe ( could be wrong ).
I don''t know of any standard functions for parsing math formulae, but it probably wouldn''t be too hard to write a simple one, a little longer if you want it to honor the order of operations.
As for this:
You should have a "\0" at the end, and it is alot easier to declare a string like this:
As for this:
char expression[50]= {"1","+","2","*","3","/","5"};
You should have a "\0" at the end, and it is alot easier to declare a string like this:
char expression[]= "1+2*3/5";
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
The only problem with parsing expressions like that (which is actually quite easy in its basic form) is in the priority of arithmetic operators (which is somewhat less trivial unless the expression is fully parenthesised). I actually had to write a program to do exactly that for my Data Structures class; the easiest way, according to my teacher (which was exactly what we all did in our assignments) is to first parse the expression and transform it from infix to postfix notation, which makes evaluation completely trivial. (I''d suggeset you Google a bit for infix/postfix notation and arithmetic expression parsing if you don''t know what I''m talking about.)
I wrote this, it seems to work except with screwy brackets that don't match.
Sample Output:
EDIT: Fixed a bug other than the ones stated above.
[edited by - smart_idiot on November 28, 2002 1:18:34 AM]
#include <iostream>#include <string>#include <cstdlib>#include <cmath>using namespace std;double CalcExpression(const char *s /*The string */, unsigned int op_level = 0, // Presedence of the operation, i.e., // 0 == do everything, // 1 == addition/subtraction, // 2 == multiplication/division, // 3 == exponents, // 4 == give me the next number and ignore everything else. const char **end = NULL) // Stores where we were when we quit parsing. { while(*s==' ') ++s; // skip any spaces. const char *eon = s; // end of number double value; switch(*s) { case 0: throw "Parse Error: Expected a value."; case '(': // Begin bracket, use it's contents. value = CalcExpression(s+1, 0, &eon); break; case '-': // Use the negetive of the following value value = -CalcExpression(s+1, 4, &eon); break; default: // Read it as a number. value = strtod(s, const_cast<char **>(&eon)); } if(eon==s) // Unable to read value throw "Parse Error: Expected a value."; while(true) { while(*eon==' ') ++eon; // Skip spaces switch(*eon) { case 0: // End of string { if(end) *end = eon; return value; } case '+': // Add if(op_level > 1) { if(end) *end = eon; return value; } else value = CalcExpression(eon+1, 1, &eon) + value; break; case '-': // Subtract if(op_level > 1) { if(end) *end = eon; return value; } else value = CalcExpression(eon+1, 1, &eon) - value; break; case '*': // Multiply if(op_level > 2) { if(end) *end = eon; return value; } else value = CalcExpression(eon+1, 2, &eon) * value; break; case '/': // Divide if(op_level > 2) { if(end) *end = eon; return value; } else value = CalcExpression(eon+1, 2, &eon) / value; break; case '^': // Exponent if(op_level > 3) { if(end) *end = eon; return value; } else value = pow(CalcExpression(eon+1, 3, &eon), value); break; case '(': // Multiply by whatever is in the brackets value *= CalcExpression(eon+1, 0, &eon); break; case ')': // End of bracket, return. { if(end) *end = eon+1; return value; } default: throw "Parse Error: Expected an operator."; } } }double CalcExpression(const string &str) { return CalcExpression(str.c_str()); }int main(void) { string expression; while(true) { getline(cin, expression); try { cout << CalcExpression(expression) << endl; } catch(const char *error) { cout << error << endl; } } return 0; }
Sample Output:
3+36 // Right1+3*310 // Right3*3+110 // Right(1+1)*36 // Right(2+2)*(2+2)16 // Right(((3)))3 // Right5(1+2)15 // Bonus(1+2)5Parse Error: Expected an operator. // Acceptable2*(2*520 // Should generate an error, but could be considered a 'feature'2)+42 // Should generate an error3**3Parse Error: Expected a value. // Right9asdf4Parse Error: Expected an operator. // Right
EDIT: Fixed a bug other than the ones stated above.
[edited by - smart_idiot on November 28, 2002 1:18:34 AM]
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
I did something a couple of years ago that was like that. It was a complete ''eval'' function I called it and could do every operator as well as accepting variables with multiple args and stuff. It was very cool but because I wrote it a couple of years ago the code was such a load of s_*T that I scrapped it. It worked though...
Thanks everyone -- especially for that code.
The "I''m a Win32 programmer..." was geared toward the getline() function. The WinAPI functions take care of that (i.e. so you just give them a pointer to point to it with and you''re done).
Anyway, thanks alot!
--Ax
The "I''m a Win32 programmer..." was geared toward the getline() function. The WinAPI functions take care of that (i.e. so you just give them a pointer to point to it with and you''re done).
Anyway, thanks alot!
--Ax
-Ax
Hi
You can also check out my homepage..i got a function parser there too. It''s a bit more powerful (supports cos, sin, tan, sqrt etc. and variables) and comes with full source
Runicsoft -- home of my open source Function Parser and more
You can also check out my homepage..i got a function parser there too. It''s a bit more powerful (supports cos, sin, tan, sqrt etc. and variables) and comes with full source
Runicsoft -- home of my open source Function Parser and more
Heya Ax,
The actual solution to your problem depends on something key to the problem. Do you want to decide whether or not a mathematical expression is valid, or do you actually want to calculate the value of a valid expression.
Deciding whether or not an expression is valid can be done in about 50 lines of code, inside of a single function. The process is based upon matching parens and deciding which operators can follow any other token. I think I still have the code for this if you need it.
The second problem of evaluating the expression is a bit more difficult. In order to solve this quickly you need to write what''s called a "recursive-descent parser." The RDP handles the problem of parens, order of operation and everything else. It basically takes each operator and then descends into the expression recursively in order to build a tree where children of the operator are either numbers or other operators with higher priority.
I believe I still have the code for this as well.
Best Regards,
Jeromy "Maverick" Walsh
------------------------
"The question isn''t how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" -Boondock Saints
The actual solution to your problem depends on something key to the problem. Do you want to decide whether or not a mathematical expression is valid, or do you actually want to calculate the value of a valid expression.
Deciding whether or not an expression is valid can be done in about 50 lines of code, inside of a single function. The process is based upon matching parens and deciding which operators can follow any other token. I think I still have the code for this if you need it.
The second problem of evaluating the expression is a bit more difficult. In order to solve this quickly you need to write what''s called a "recursive-descent parser." The RDP handles the problem of parens, order of operation and everything else. It basically takes each operator and then descends into the expression recursively in order to build a tree where children of the operator are either numbers or other operators with higher priority.
I believe I still have the code for this as well.
Best Regards,
Jeromy "Maverick" Walsh
------------------------
"The question isn''t how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" -Boondock Saints
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Actually, I''m doing both (but based on the second). In other words, this project is for an engineering project at school (vs. a science project). The program, so far, checks whether the inputted formula is valid then sends the formula over to the code I got from smart_idiot (unless it has an alternate variable, then the program extracts the variable and fixes the buffer up without the variable and THEN sends it over to smart_idiot''s code).
So, the program asks for the specific kind of formula''s (X=?, X=X?, ?=X^2*X?, and so forth...) sides (left/right, depending upon whether or not they are needed). There are a couple of problems with the code that I can very readily see fixed with the RDP, though. For instance, X^? could be the highest priority and be dealt with...Anyway, I be interested in that code or a resource recommended on how to write an RDP. Also, I''m looking into infix/postfix (of course, that might be what you''re using in the RDP). At any rate, thanks.
--Ax (cbrthrash@netscape.net)
So, the program asks for the specific kind of formula''s (X=?, X=X?, ?=X^2*X?, and so forth...) sides (left/right, depending upon whether or not they are needed). There are a couple of problems with the code that I can very readily see fixed with the RDP, though. For instance, X^? could be the highest priority and be dealt with...Anyway, I be interested in that code or a resource recommended on how to write an RDP. Also, I''m looking into infix/postfix (of course, that might be what you''re using in the RDP). At any rate, thanks.
--Ax (cbrthrash@netscape.net)
-Ax
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement