So, I am writing a program which takes the input (a mathematical expression) and converts it into postfix notation and then print it out to the user. When I perform this program on simple mathematical expressions (i.e. 5 + 1 - 3 * 2) it works great. The problem is when I include parentheses. It prints all of the mathematical operators on the last line instead of their proper place. I need the mathematical operators to be in their proper spot. (i. e. 5 1 + 3 - 2 *). Any suggestions?
The real output of this statement 5 - ( 2 * 3 ) + 5 is 5 2 3 5 * - + I need it to look like 5 2 3 * - 5 +
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
using namespace std;
int priority(string item) //prioritizing the operators
{
if(item == "(" || item == ")")
{
return 0;
}
else if(item == "+" || item == "-")
{
return 1;
}
else if(item == "/" || item == "*")
{
return 2;
}
}
void welcome()
{
cout << "blah blah!" << endl;
}
int main()
{
welcome(); // welcome text
stack <string> myStack;
char line[256];
cin.getline( line, 256);
string exp = line;
string item;
string output = "";
istringstream iss(exp);
iss >> item;
while(iss)
{
if(item != "+" && item != "-" && item != "/" && item != "*" && item != "(" && item != ")") //If the char is a number
{
cout << item << endl;
}
else if(myStack.size() == 0) // If the stack is empty
{
myStack.push(item);
}
else if( item == "+" || item == "-" || item == "/" || item == "*") //If the char is an operator
{
if(priority(myStack.top()) < priority(item)) // the item on the stack is greater priority than the array item
{
myStack.push(item);
}
else
{
while(myStack.size() > 0 && priority(myStack.top()) >= priority(item)) //while the stack contains something, and the item on
{
string dpu = myStack.top();
myStack.pop();
output = output + dpu + " ";
}
myStack.push(item);
}
}
else if(item == "(") // left peren
{
myStack.push(item);
}
else if(item == ")") // right peren
{
while(myStack.top() != "(")
{
string dpu = myStack.top();
myStack.pop();
output = output + dpu + " ";
}
myStack.pop();
}
iss>> item;
}
while (myStack.size() > 0 )
{
string dpu = myStack.top();
output = output + dpu + " ";
myStack.pop();
}
cout<< output << endl;
}
well... in your code the numbers are always printed before anything else:
if (item != "+" && item != "-" && item != "/" && item != "*" && item != "(" && item != ")") //If the char is a number
{
cout << item << endl;
}
I'm not familiar with the notation you are requesting, but a stack doesn't seem to me the right datastructure for this task... using a tree seems better to me, since you are parsing
Related
I am trying to put tokens into a queue. However, when I try to put in a number that has more than one digit (i.e., 10, 123 ) it reads them as separate digits. Can someone tell me what I'm doing wrong? I've tried string insert and append and none of them seem to work
queue <string> getTokens(string token){
int a = (int) token.length();
string temp;
queue <string> numbers;
char t;
for (int i =0; i <a; i++){
t = token[i];
while (!isdigit(t)){
if (t=='+' || t=='-' || t=='/' || t=='*' || t=='^'){
string temp1;
temp1 += t;
numbers.push(temp1);
temp1.clear();
}
else if (t=='(' || t==')'){
string temp1;
temp1 += t;
numbers.push(temp1);
temp1.clear();
}
else if (!isalpha(token[i-1]) && t == 'e' && !isalpha(token[i+1])){
string e = "2.718";
numbers.push(e);
}
else if (!isalpha(token[i-1]) && t == 'p' && token[i+1]== 'i' && !isalpha(token[i+2])){
string pi = "3.14169";
numbers.push(pi);
}
break;
}
//if it is one single number
if (!isdigit(token[i-1]) && isdigit(t) && !isdigit(token[i+1])){
string tt;
tt += t;
numbers.push(tt);
}
//if there is more than one number
else if ((isdigit(t) && isdigit(token[i+1])) || (isdigit(token[i-1]) && isdigit(t))){ //if it is a number
string temp2;
string temp3="k";
string temp4;
//cout << t;
//int j=1;
if( isdigit(token[i])){
temp2 += t;
cout<<"temp2 : "<<temp2<<endl;
cout <<"temp3 :" << temp3<<endl;
//temp2.clear();
temp3 +=temp2;
}
temp4.append(temp3);
temp4 +=temp3;
//cout<<"hi"<<endl;
cout << "This is temp4: " << temp4 <<endl;
//cout << "this is temp3: " << temp3<< endl;
//temp2.clear();
//cout<<temp2 << "yo";
//temp3.assign(temp2);
//cout << "temp3 is : "<< temp3;
}
else
continue;
}
return numbers;
}
int main (){
string expression;
getline(cin,expression);
cout << expression;
queue <string> ts;
ts= getTokens(expression);
}
At every Iteration temp2 temp3 temp4 variable's value will get reset
so it does not hold previous iteration's value.
I think this is where you might be facing problem.
try to declare it outside for loop and clear it after you obtain desirable output, for next use
//if there is more than one number
else if ((isdigit(t) && isdigit(token[i+1])) || (isdigit(token[i-1]) && isdigit(t))){
//if it is a number
string temp2;
string temp3="k";
string temp4;
I hope this might help
I'm aware that there's already stuff here regarding this but I'm just posting to check if my logic lines up with my code (if I'm thinking about this whole infix Postfix thing the way I should be).
The code I've seen regarding this topic on this site look a little different from mine. I'm kind of a novice at C++. Anyway, my code so far looks like it is just fine and should work just fine but it's not working the way it should. I've included my thought process as comments in the code below. Please let me know if what I'm thinking is okay.
Here's the code:
#include <iostream>
#include <stack>
#include <sstream>
#include <string>
using namespace std;
int priority (string item)
{
int prior = 0;
if (item == "(")
{
prior = 1;
}
if ((item == "+") || (item == "-"))
{
prior = 2;
}
else if ((item == "*") || (item == "/"))
{
prior = 3;
}
else
{
prior = 4;
}
return prior;
}
int main()
{
stack<string> st;
string output;
cout << "Welcome. This program will calculate any arithmetic expression you enter" << endl;
cout << "Please enter an arithmetic expression below: " << endl;
char line[256];
cin.getline(line, 256);
string exp;
exp = line;
cout << "This is the expression you entered: ";
cout << exp << endl;
string item;
istringstream iss(exp);
iss >> item;
// While there are still items in the expression...
while ( iss )
{
// If the item is a number
if (isdigit('item') == true)
{
output = output + " " + item;
}
// If the stack is empty
else if (st.size() == 0)
{
st.push(item);
}
// If the item is not a number
else if (isdigit('item') == false)
{
// convert that item in the expression to a string
atoi(item.c_str());
int prior1 = 0;
int prior2 = 0;
// If that string is a LEFT PARENTHESIS
if (item == "(")
{
st.push(item);
}
// If that string is a RIGHT PARENTHESIS
else if (item == ")")
{
while ((st.empty() == false) && (st.top() != "("))
{
output = st.top() + " ";
st.pop();
}
st.pop();
}
else
{
// store what is returned from "priority" in "prior1"
prior1 = priority(item);
// pass item on top of the stack through "priority"
// store that in "prior2;
prior2 = priority(st.top());
// while loop here, while item has a higher priority...
// store numbers in a variable
while (prior1 > prior2)
{
output = output + " " + st.top();
st.pop();
prior2 = priority(st.top());
}
}
}
}
while (st.empty() == false)
{
output = st.top() + " ";
st.pop();
}
cout << "Here's the postfix: " << output << endl;
}
This is for evaluating postfix to an actual answer:
// EVALUATE POSTFIX
stack<int> st2;
string output2;
istringstream iss2(exp);
iss2 >> item;
while (iss)
{
// If the item is a number
if (isdigit('item') == true)
{
st.push(item);
}
if (isdigit('item') == false)
{
// store item in a variable
// pop another item off the stack
// store that in a variable.
// apply operator to both.
// push answer to the top of the stack.
int m = 0;
int n = 0;
int total = 0;
m = st2.top();
st2.pop();
n = st2.top();
st2.pop();
if (item == "+")
{
total = m + n;
st2.push(total);
}
else if (item == "-")
{
total = m - n;
st2.push(total);
// add the thing you popped of the stack with the first thing on the stack
}
else if (item == "*")
{
total = m * n;
st2.push(total);
}
else if (item == "/")
{
total = m / n;
st2.push(total);
}
}
}
cout << "Here's your answer: " << st2.top() << endl;
}
Am I thinking about this whole infix-postfix thing the way I should be? Am I on track to solving this problem? My apologies if this question seems simple. I'm kind of a novice at this. Thank you very much.
I was about to write a C++ function doing the following:
1 ---> "1st"
2 ---> "1nd"
3 ---> "3rd"
...
17657 --> "17657th"
...
i.e. produces the ordinal extension string for that number (it doesn't have to do an itoa() of the number itself). But then I thought "surely something in the standard library or boost does this already?"
Notes:
I know it's not hard to write this, there's an implementation in Python right here on SO, I just don't want to duplicate code.
I need this in English, obviously. A multi-language version would be nice for political-correctness considerations, not more than that...
Here's what I ended up writing:
const char* ordinal_suffix(int n)
{
static const char suffixes [][3] = {"th", "st", "nd", "rd"};
auto ord = n % 100;
if (ord / 10 == 1) { ord = 0; }
ord = ord % 10;
if (ord > 3) { ord = 0; }
return suffixes[ord];
}
The code golf solutions are cute, but - they really do optimize for terseness, not anything else. This is faster (although it could be made even faster by putting the suffixes in a .cpp out of the function body and making the code inlinable), much clearer, and still more terse than most other answers here.
// Returns numbers with ordinal suffix as string
// Based on https://stackoverflow.com/questions/3109978/display-numbers-with-ordinal-suffix-in-php
std::string NumberToOrdinal(size_t number) {
std::string suffix = "th";
if (number % 100 < 11 || number % 100 > 13) {
switch (number % 10) {
case 1:
suffix = "st";
break;
case 2:
suffix = "nd";
break;
case 3:
suffix = "rd";
break;
}
}
return std::to_string(number) + suffix;
}
I'm pretty sure you can adapt the four line solution at Display numbers with ordinal suffix in PHP. Unfortunately, I don't think there is such a thing in a common C++ lib.
try this...
#include <iostream>
using namespace std;
void suffix(int n, char suff[]);
// creates the ordinal suffix
// for a given number
int main()
{
char s[5];
int x;
cout << "Enter a number to find the ordinal suffix for ";
cin >> x;
suffix(52111,s);
}
void suffix(int n, char suff[])
{
if(n%100 == 11 || n%100 == 12 || n%100 == 13)
{
cout << "suffix is: " << n << "th";
cout << endl;
}
else
{
if(n%10 == 1)
{
cout << "Suffix is: " << n << "st";
cout << endl;
}
else
{
if(n%10 == 2)
{
cout << "Suffix is: " << n << "nd";
cout << endl;
}
else
{
if(n%10 == 3)
{
cout << "Suffix is: " << n << "rd";
cout << endl;
}
else
{
if(n%10 == 4 || n%10 == 5 || n%10 == 6 || n%10 == 7 || n%10 == 8 || n%10 == 9 || n%10 == 0)
{
cout << "Suffix is: " << n << "th";
cout << endl;
}
}
}
}
}
}
I used the following string function to accomplish it.
#include <string>
#include <iostream>
using namespace std;
string ordinal(int i)
{
if(i==1)
{
return "First";
}
if(i==2)
{
return "Second";
}
if(i==3)
{
return "Third";
}
if(i==4)
{
return "Fourth";
}
if(i==5)
{
return "Fifth";
}
if(i==6)
{
return "Sixth";
}
if(i==7)
{
return "Seventh";
}
if(i==8)
{
return "Eighth";
}
}
int main()
{
for(int i=0; i<8; i++)
{
cout << ordinal(i+1) << " number: ";
}
return 0;
}
#include <iostream>
#include <string>
std::string number_to_ordinal(int number)
{
// Convert number to string
std::string ordinal = std::to_string(number);
// Get the last character of the number to later determine ordinal indicator
char last_char = ordinal.back();
// Get the last two characters of the number to deal with ordinal indicator conditions
std::string last_two_char;
if(ordinal.size() > 1)
last_two_char = ordinal.substr(ordinal.size() - 2, ordinal.size());
// Determine ordinal indicator. Each number with a last character ending in '1', '2',
// and '3' require ordinal indicators of 'st', 'nd', and 'rd', respectively. However,
// numbers with the last two characters ending in '11', '12', and '13' require 'th'
// as the ordinal indicator.
if(last_two_char != "11" && last_char == '1')
ordinal += "st";
else if (last_two_char != "12" && last_char == '2')
ordinal += "nd";
else if (last_two_char != "13" && last_char == '3')
ordinal +="rd";
else
ordinal += "th"; // All other numbers require 'th' as the ordinal indicator
return ordinal;
}
///////////////////////////////////////////////////////////////////////
// Main Program
///////////////////////////////////////////////////////////////////////
int main()
{
// Test number to ordinal
for(int i = 17657; i < 17725; i++)
std::cout << number_to_ordinal(i) << std::endl;
return 0;
}
Im not sure if I used find_first of and last_of correctly, but what I want to do is that I need to print error when it finds _ on the beginning or at the end of my code, plus when it finds two or more _ next to each other, like this lol___, lol__lol, _lol_, _lol, lol_, and one more rule, _ cannot be in front of capital letter, like this lol_Lol
here is my code
std::string::size_type n;
std::string::size_type n2;
std::string::size_type n3;
std::string const ss = slovo;
n = ss.find('_');
n2 = ss.find_first_of('_');
n3 = ss.find_last_of('_');
if (n2 == std::string::npos && n3 == std::string::npos) {
cout << "chyba" << endl;
}else if(n == std::string::npos){
string s = transform(slovo);
cout << s << endl;
}else{
string s = untransform(slovo);
cout << s << endl;
}
EDIT>
if ( !ss.empty() && ss.front() == '_' && ss.back() == '_' )
{
cout << "Chyba" << endl;
} else {
if ( ss.length() > 3 && ss.find( '__', 1, ss.length() - 2 ) != std::string::npos )
{
if (n == std::string::npos){
string s = transform(slovo);
cout << s << endl;
}else{
string s = untransform(slovo);
cout << s << endl;
}
}else{
cout << "chyba" << endl;
}
}
EDIT2:
cin >> slovo;
}
std::string::size_type n;
std::string const ss = slovo;
n = ss.find('_');
// kontrola podtrznika
if ( ss.empty() && ss[0] == '_' && ss[ss.length() - 1] == '_' )
{
cout << "chyba" << endl;
}
if ( ss.length() > 3 && ss.find( "__", 1, ss.length() - 2 ) != std::string::npos )
{
cout << "chyba" << endl;
}
if (n == std::string::npos)
{
string s = transform(slovo);
cout << s << endl;
}else{
string s = untransform(slovo);
cout << s << endl;
}
if those functions return npos it means the character couldn't be found in the string. So if one of them returns that, all 3 of them will.
So this code outputs 'chyba' it there's no _ in the string or calls untransform otherwise. From your description, that's not what you intend.
You really need to scan through the string for all those conditions. And if you want to check the first and last characters of the string, use ss[0] and ss[ss.length() - 1] (taking appropriate care you don't have a string of length 0 or 1).
It is obvious that the two function calls will give you the same result
n = ss.find('_');
n2 = ss.find_first_of('_');
In this context they are equivalent.
If I have understood you correctly you need to determine whether the first and the last characters in a string are underscores and whether the string contains two adjacent undescores within itself.
To determine the first case it is simple to write
if ( !ss.empty() && ss.front() == '_' && ss.back() == '_' )
{
//...
}
To find at least two adjacent underscores excluding the first and the last characters you can write
if ( ss.length() > 3 && ss.find( "__", 1, ss.length() - 2 ) != std::string::npos )
{
//...
}
So, I'm having issues with this program. Can anyone tell me what I'm doing wrong here? The program is supposed to take a simple infix notation mathematical expression (e.g. "5 - 2 + 1") and then convert it to (e.g. "5 2 - 1 +") and then solve it which would be 4. It converts just fine but as soon as it gets into the evaluating part, it doesn't show anything on the command prompt. Can I get some help? Thanks!
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int priority(string item) //prioritizing the operators
{
if(item == "(" || item == ")")
{
return 0;
}
else if(item == "+" || item == "-")
{
return 1;
}
else //if(item == "/" || item == "*") <-- guess didnt need to define this one
{
return 2;
}
}
void welcome()//welcome text
{
cout << "Welcome to this program!" << endl;
cout << "Please enter your equation" << endl;
}
int main()
{
welcome(); // welcome text
stack <string> myStack; // initializing the stack.
char line[256];
cin.getline( line, 256); // this and the proceeding line get the input.
string exp = line;
string item;
string postFix;
istringstream iss(exp);
iss >> item;
while(iss)
{
if(item != "+" && item != "-" && item != "/" && item != "*" && item != "(" && item != ")") //If the char is a number
{
cout << item;
postFix = postFix + item;
}
else if(myStack.size() == 0) // If the stack is empty
{
myStack.push(item);
}
else if( item == "+" || item == "-" || item == "/" || item == "*") //If the char is an operator
{
if(priority(myStack.top()) < priority(item)) // the item on the stack is greater priority than the array item
{
myStack.push(item);
}
else
{
while(myStack.size() > 0 && priority(myStack.top()) >= priority(item)) //while the stack contains something, and the item on
{
cout << myStack.top();
postFix = postFix + item;
myStack.pop();
}
myStack.push(item);
}
}
else if(item == "(") // left peren
{
myStack.push(item);
}
else if(item == ")") // right peren
{
while(myStack.top() != "(")
{
cout << myStack.top();
postFix = postFix + item;
myStack.pop();
}
myStack.pop();
}
iss >> item;
}
while (myStack.size() > 0 ) //When nothing is left to evaluate
{
cout << myStack.top();
postFix = postFix + myStack.top();
myStack.pop();
}
cout << endl;
//PART 2
int x1;
int x2;
int x3;
stack<int> thirdStack;
string exp2 = postFix;
string item2;
istringstream iss2(exp2);
iss2 >> item2;
while(iss2)
if(item2 != "+" && item2 != "-" && item2 != "/" && item2 != "*") //if its a number
{
int n;
n = atoi(item2.c_str());
thirdStack.push(n);
}
else if( item2 == "+" || item2 == "-" || item2 == "/" || item2 == "*") //if its an operator
{
x1 = thirdStack.top();
thirdStack.pop();
x2 = thirdStack.top();
thirdStack.pop();
if(item2 == "+")
{
x3 = x1 + x2;
thirdStack.push(x3);
}
else if(item2 == "-")
{
x3 = x1 - x2;
thirdStack.push(x3);
}
else if(item2 == "/")
{
x3 = x1 * x2;
thirdStack.push(x3);
}
else if(item2 == "*")
{
x3 = x1 / x2;
thirdStack.push(x3);
}
}
}
cout << "The conversion into infix notation is" + thirdStack.top() << endl;
}
There are a number of problems with this code.
In part 1, while your code appears to write out the correct postfix conversion, the postFix string it builds up isn't the same thing.
For example, in some places you have code like this:
cout << myStack.top();
postFix = postFix + item;
You're writing out myStack.top() but adding item to your postFix result. It should be this:
cout << myStack.top();
postFix = postFix + myStack.top();
In addition, you ought to be including spaces between each item that you add to the postFix string. So your result should be 5 2 - 1 + rather than 52-1+. Otherwise when trying to interpret that expression, the first item is going to be interpreted as 52.
Then in part 2, you're missing a call to iss2 >> item2; at the end of the while loop. You're basically just interpreting the first item over and over again, so the code will end up in an infinite loop.
And in your calculations, you have the operand order incorrect. This doesn't matter for addition and multiplication, but it does for subtraction and division. For example, the substraction calculation should be x3 = x2 - x1; rather than x3 = x1 - x2;.
Finally, when streaming out the result you've got a plus when you should have a stream operator. It should look like this:
cout << "The conversion into infix notation is" << thirdStack.top() << endl;