Hi, I am trying to work on a simple calculator to evaluate some strings (using PEMDAS). I know the format of the strings will always be: "(# ? # ) ? # ? #" where '#' is a single digit positive whole number greater than 0 and '?' is an operand (the only ones it could be are '+' '-' '*' '/').
I am trying to add code where I input a string in the format described above, and I get an output equal to the result.
I looked through some other forum posts as well as some stuff online, but I wasn't seeing a good way to do this. I am also used to javaScript coding, so I might just be missing something obvious. My original code was returning non English characters like:
My code no longer returns those characters, but seems to just return random all capital things (ignoring the first output), and one number that should be the result of it's calculation. The problem is, for 5+5 it returned 106.
My end goal is to evaluate the full string format, but for now I just want to get the first calculation done. After that I will finish off the rest of the code and report back as to if the new code works. Thanks in advance!
Here is what I have so far:
// C++ code
//
String given_eq = "(5+5)+7/7";
int result = 0;
String result_string = given_eq;
String current_best_op = "";
//op scores: '*', '/' = 2|| '+', '-' = 1
int current_best_op_score = 0;
int op_score_other = 0;
String op_to_check = "";
String final_op_string = "";
int best_op_pos = 0;
//how to eval:
//first I will use if statements to evaluate the substring 1,2,3
//Then I will (going left to right) look at the next operand. If it
//comes before the current one in PEMDAS I will save it as the new thing.
//If not, I will use the first.
void setup()
{
Serial.begin(11500);
Serial.print("First thing to do: " + given_eq.substring(1,4));
//eval in ()
//the code below is going to be changed later to work wih other
//operands. For now, I am just testing with addition
result_string = given_eq[1] + given_eq[3];
Serial.print("\n THE ANSWER IS: ");
Serial.print(result_string);
//set best op to next op
current_best_op = given_eq[5];
//set op score
if (current_best_op == "*" || current_best_op == "/"){
current_best_op_score = 2;
} else {
current_best_op_score = 1;
}
//This loop will be used to find the next ooperation I should do
//as well as the position of the symbol. The loop works.
for (int op_loop_1 = 5; op_loop_1 < given_eq.length(); op_loop_1++){
op_score_other = 0;
//set op string
op_to_check = given_eq[op_loop_1];
//check if op is 'better'
if (op_to_check == "*" || op_to_check == "/"){
op_score_other = 2;
} else {
op_score_other = 1;
}
//final check
if (op_score_other > current_best_op_score) {
final_op_string = op_to_check;
best_op_pos = op_loop_1;
current_best_op = given_eq[op_loop_1];
op_score_other = 0;
}
}
//print op chosen
Serial.print("\n NEXT OP: ");
Serial.print(current_best_op);
}
void loop()
{
}
Thanks! So if I want to do 9+9 I still just subtract 48 from each number before the operation? This also seems to work for my other operations which is great!
a common approach is to have 2 separate stacks (arrays): one for values and the other for operations.
the input can be processed one char at a time. a digit increases the value of the current value on the value stack. an operation char is pushed on the operation stack, as well as incrementing the value stack index.
also when an operation is recognized, an operation can be computed by popping two values of the value stack, performing the indicated operation and pushing the result back on the stack.
while this approach may sound overcomplicated, i think you'll realize, if you haven't already, that such an approach is required when operations need to be deferred as in the case of processing expressions withing parenthesis or handling priority operation (i.e. multiplications befoer addition)
#include <stdio.h>
#include <stdlib.h>
const int MaxOp = 10;
char op [MaxOp];
int opIdx;
const int MaxVal = 10;
int val [MaxVal];
int valIdx = 0;
void
calc (
char c )
{
int val1;
int val2;
printf ("calc: c %c\n", c);
switch (c) {
case '0'...'9':
val [valIdx] = 10*val [valIdx] + c - '0';
break;
case '+':
case '-':
case '*':
case '/':
if (MaxVal <= ++valIdx) {
printf ("Error: MaxVal exceeded\n");
exit (1);
}
op [opIdx++] = c;
break;
case '=':
if (1 > valIdx) {
printf ("Error: too few vals - valIdx %d\n", valIdx);
exit (1);
}
val1 = val [--valIdx];
val2 = val [--valIdx];
switch (op [--opIdx]) {
case '+':
val [valIdx++] = val1 += 2;
break;
case '-':
val [valIdx++] = val1 -= 2;
break;
}
printf (" %6d\n", val1);
break;
}
}
// -----------------------------------------------------------------------------
int
main ()
{
char c;
while (c = getchar ()) {
calc (c);
}
return 0;
}