Check if a string contains a valid postfix expression - c++

I have a string that needs to be check for a valid postfix expression.
A valid postfix string is 1 2 + but not 1 2+ since each character needs a space. Also, since it's a string, you can enter words, but they should return -1 for this function.
I have tried using vector array with strings and checking for valid ints, but when the user enters letters this obviously creates a problem.
string postfix = "1 2 +"; // valid
string postfix = "soemthing"; // error
string postfix = "1 2+" ; // error since there is no space.
if (!isdigit(postfix[0]))
return -1;
int t;
string line = "55 124 4 5";
std::vector <int> ints;
std::istringstream iss ( line, std::istringstream::in);
int main() {
while (iss >> t )
{
ints.push_back(t);
}
if (!digit(ints[0]) || !digit(ints[0]))
return -1;
}
~

From this post you can get the algorithm to check. In c++:
int isValid(string postfix) {
int l = postfix.size();
char c;
bool numStarted = false;
int counter = 0;
for (int i = 0; i < l; i++) {
c = postfix.at(i);
if (numStarted == true && c == ' ') {
numStarted = false;
} else if (numStarted == false && c == ' ') {
return -1;
} else if (c == '-' || c == '+' || c == '*' || c == '/') {
if (counter < 2 || numStarted) {
return -1;
}
counter--;
numStarted = true;
} else if (!isdigit(c)) {
return -1;
} else if (!numStarted && isdigit(c)) {
counter++;
numStarted = true;
}
}
return (counter == 1 ? 1 : -1);
}
To test this:
int main(int argc, char** argv) {
string postfix1 = "1 2 +"; // valid
string postfix2 = "soemthing"; // error
string postfix3 = "1 2+"; // error since there is no space.
cout << isValid(postfix1) << endl;
cout << isValid(postfix2) << endl;
cout << isValid(postfix3) << endl;
return 0;
}
output:
1
-1
-1

Related

Trying to fix a string function that takes a string and change it by replacing some words

I am trying to fix a function that takes a string a checks whether it can find the numbers 4 and 5 and change them to N
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
string Newstring(string& Text);
int main()
{
while (1)
{
string head = "";
cout << "Input a string: ";
getline(cin, head);
cout << '\n';
cout << "The new string is: ";
cout << Newstring(head);
cout << '\n';
cout << "This is the end";
cin.ignore();
system("cls");
}
system("pause");
return 0;
}
string Newstring(string& Text)
{
string NewText = "";
for (int i = 0; i < Text.length(); i++)
{
if (i == '4' || i == '5')
{
i = 'N';
NewText += Text[i];
}
}
return NewText;
}
Input a string: 45fj ji
The new string is:
This is the end
This is the output and it does not show the new string
You're checking and updating the index i instead of the Text[i].
Check for
Text[i]=='4' && Text[i]=='5' and also update
Text[i]='N'
Change this:
if (i == '4' || i == '5')
{
i = 'N';
NewText += Text[i];
}
to this:
if (Text[i] == '4' || Text[i] == '5') {
NewText += 'N';
} else {
NewText += Text[i];
}
ERROR 1
you are checking if iteration through loop is equal to 4 or 5 with:
if (i == '4' || i == '5')
ERROR 2
You are assigning letter N to integer variable:
i = 'N';
But here is my ultimate solution for this problem:
std::string Newstring(const std::string& Text)
{
std::string NewText (Text);
for (int i = 0; i < Text.length(); i++)
if (NewText[i] == '4' || NewText[i] == '5')
NewText[i] = 'N';
return NewText;
}
You function need to be something like this:
string Newstring(string& Text)
{
string NewText = "";
for (int i = 0; i < Text.length(); i++)
{
if ((Text[i] == '4') || (Text[i] == '5'))
{
NewText += 'N' ;
}
else
{
NewText += Text[i];
}
}
return NewText;
}

Vector push_back & pop_back

I'm working on an assignment. I have coded the assignment and everything is working as it should, except my output is missing a digit. I also attached the sample output. After inputting a a mathematical expression into a string, for example 35 * 4 - 6 / (9 + 3), a digit is dropped. In normal order, the 3 will be missing. In reverse order, the 9 will be missing. I am not understanding why this happening.
Any help, or I would prefer some guidance, would be appreciated. Am I using the push_back incorrectly? The code is as follows:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<string> split(string);
vector<string> splitback(string);
int main()
{
vector<string> vectorExpression;
string expression;
cout << "Enter an expression :";
getline(cin, expression);
vectorExpression = split(expression);
for (int i = 0; i < vectorExpression.size(); i++)
{
cout << vectorExpression[i] << endl;
}
cout << endl;
vectorExpression = splitback(expression);
for (int i = 0; i < vectorExpression.size(); i++)
{
cout << vectorExpression[i] << endl;
}
system("pause");
return 0;
}
vector<string> split(string expression)
{
vector<string> splitExpression;
string digit = "",
x = "";
for (int i = 0; i < expression.size(); i++)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = digit + expression[i];
}
else if (expression[i] != ' ')
{
x = "";
x = x + expression[i];
splitExpression.push_back(x);
}
else
{
if (digit.size() > 0)
{
splitExpression.push_back(digit);
digit = "";
}
}
}
if (digit.size() > 0)
{
splitExpression.push_back(digit);
}
return splitExpression;
}
vector<string> splitback(string expression)
{
vector<string> splitBackExpression;
string number = "",
x = "";
for (int i = expression.size() - 1; i >= 0; i--)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
number = expression[i] + number;
}
else if (expression[i] != ' ')
{
x = "";
x = x + expression[i];
splitBackExpression.push_back(x);
}
if (number.size() > 0)
{
splitBackExpression.push_back(number);
number = "";
}
}
return splitBackExpression;
}
Your split function is wrong, you forget to add digits, correct one would be
vector<string> split(string expression)
{
vector<string> splitExpression;
string digit = "",
x = "";
for (int i = 0; i < expression.size(); i++)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = digit + expression[i];
}
else
{
// don't forget digit if there was one
if (digit.size() > 0)
{
splitExpression.push_back(digit);
digit = "";
}
// also add what comes next if not a whitespace
if (expression[i] != ' ')
{
x = expression[i];
splitExpression.push_back(x);
}
}
}
if (digit.size() > 0)
{
splitExpression.push_back(digit);
}
return splitExpression;
}
Here is the final answer to my own question, or at least the solution I came up with the help from here.
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<string> split(const string&);
vector<string> splitback(const string&);
int main()
{
vector<string> forwardExpression,
reverseExpression;
string expression;
cout << "Enter an expression :";
getline(cin, expression);
//////////////////////////////////////////////////
// FORWARD DISPLAY OF EXPRESSION //
//////////////////////////////////////////////////
forwardExpression = split(expression);
cout << "'" << expression << "'" << " split into individual entities forwards
yields:" << endl;
cout << endl;
for (int i = 0; i < forwardExpression.size(); i++)
{
cout << forwardExpression[i] << endl;
}
cout << endl;
//////////////////////////////////////////////////
// BACKWARD DISPLAY OF EXPRESSION //
//////////////////////////////////////////////////
reverseExpression = splitback(expression);
cout << "'" << expression << "'" << " split into individual entities
backwards yields:" << endl;
cout << endl;
for (int i = 0; i < reverseExpression.size(); i++)
{
cout << reverseExpression[i] << endl;
}
cout << endl;
system("pause");
return 0;
}
//////////////////////////////////////////////////
// FORWARD FUNCTION OF EXPRESSION //
//////////////////////////////////////////////////
vector<string> split(const string &expression)
{
vector<string> splitExpression;
string digit = "",
x = "";
for (int i = 0; i < expression.size(); i++)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = digit + expression[i];
}
else
{
if (digit.size() > 0)
{
splitExpression.push_back(digit);
digit = "";
}
if (expression[i] != ' ')
{
x = expression[i];
splitExpression.push_back(x);
}
}
}
if (digit.size() > 0)
{
splitExpression.push_back(digit);
}
return splitExpression;
}
//////////////////////////////////////////////////
// BACKWARD FUNCTION OF EXPRESSION //
//////////////////////////////////////////////////
vector<string> splitback(const string &expression)
{
vector<string> splitBackExpression;
string digit = "",
x = "";
for (int i = expression.size() - 1; i >= 0; i--)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = expression[i] + digit;
}
else
{
if (digit.size() > 0)
{
splitBackExpression.push_back(digit);
digit = "";
}
if (expression[i] != ' ')
{
x = expression[i];
splitBackExpression.push_back(x);
}
}
}
if (digit.size() > 0)
{
splitBackExpression.push_back(digit);
}
return splitBackExpression;
}

I need to know how to extend the program so that it reads and converts all input numbers until end of file on standard input

I am writing code where a user will enter a roman numeral and the output will be a regular number. I have accomplished this, however I'm having trouble with the next part, which is to:
Extend the program so that it reads and converts all input numbers until end of file on standard input. You'll probably be able to do this simply by adding an appropriate "reading loop" around the code that reads a single line.
My current code is:
#include<iostream>
#include<string>
using namespace std;
int value(char r){
if(std::toupper(r) == 'I')
return 1;
if (std::toupper(r) == 'V')
return 5;
if (std::toupper(r) == 'X')
return 10;
if (std::toupper(r) == 'L')
return 50;
if (std::toupper(r) == 'C')
return 100;
if (std::toupper(r) == 'D')
return 500;
if (std::toupper(r) == 'M')
return 1000;
return -1;
}
int romantoArabic(string &str){
int res = 0;
for (int i=0; i<str.length(); i++)
{
int s1 = value(str[i]);
if (i+1 < str.length())
{
int s2 = value(str[i+1]);
if (s1 >= s2)
{
res = res + s1;
}
else
{
res = res + s2 - s1;
i++; // Value of current symbol is
}
}
else
{
res = res + s1;
i++;
}
}
return res;
}
int main(){
string str;
cout<<"";
cin>>str;
cout << ""<< romantoArabic(str) << endl;
return 0;
}
Say, for example, the user was to enter the following (BTW, this is what needs to be entered, and at the moment my code does not allow me to do):
i
ii
iii
iv
v
vi
vii
viii
ix
My output is:
1
When it should be:
1
2
3
4
5
6
7
8
9
while (cin >> str) {
cout << ""<< romantoArabic(str) << endl;
}

Parenthesized Expression (Infix and Post fix) Conversion and Evaluation

I have the below code working fine but outputs only 2nd input, not 1st or 3rd.
My code should get fully parenthesized expression from console and convert it to postfix expression and then that postfix expression should be evaluated in modulo 10.Therefore, all results (including intermediate results) are single decimal digits in {0, 1, …, 9}. I need to store only single digits in the stack.
My inputs and outputs are shown in below.I only got 2nd input correctly.
Please advise.
Expression 1: (((2+(5^2))+7)
Answer:
252^+7+
4 in modulo 10
Expression 2: ((((2+5)*7)+((9*3)*2))^2)
Answer:
25+7*93*2*+2^
9 in modulo 10
Expression 3: ((((2*3)*(4*6))*7)+(((7+8)+9)*((2+4)*((7+8)+9))))
Answer:
23*46*7*789++24+78+9+**+
4 in modulo 10
My code:
#include <iostream>
#include <string>
#include<sstream>
using namespace std;
class STACK {
private:
char *s;
int N;
public:
STACK(int maxN) {
s = new char[maxN];
N = 0;
}
int empty() const {
return N == 0;
}
void push(char item) {
s[N++] = item;
}
char pop() {
return s[--N];
}
};
int main() {
string infixExpr;
string postfixExpr = "";
cout << "Enter infix expression:" << endl;
cin >> infixExpr; //converting to postfix read from the input
int N = infixExpr.size(); //strncpy(a, infixExpr.c_str(), N);
STACK ops(N);
char ch;
for (int i = 0; i < N; i++) {
if (infixExpr[i] == ')')
{
ch = ops.pop();
postfixExpr.push_back(ch);
}
if ((infixExpr[i] == '+') || (infixExpr[i] == '*') || (infixExpr[i] == '^'))
ops.push(infixExpr[i]);
if ((infixExpr[i] >= '0') && (infixExpr[i] <= '9'))
{
//cout << infixExpr[i] << " ";
postfixExpr.push_back(infixExpr[i]);
}
}
cout <<"Answer :"<<endl;
cout <<postfixExpr <<endl; //evaluate post fix expression
N = postfixExpr.size();
STACK save(N);
int result;
int num;
int count = 0;
string temp = "";
for (int i = 0; i < N; i++) {
// cout << " Expr[i] " << postfixExpr[i] << endl;
if (postfixExpr[i] == '+')
save.push((save.pop() + save.pop()) % 10);
if (postfixExpr[i] == '*')
save.push((save.pop() * save.pop()) % 10);
if (postfixExpr[i] == '^') {
count = save.pop() - '0';
num = save.pop() - '0'; //cout << result << "- " <<"-" <<count<<endl;
result = 1;
for(int j = 1; j <= count; j++)
{
result = result * num;
result = result % 10;
}
stringstream convert;
convert << result;//add the value of Number to the characters in the stream
temp = convert.str();//set Result to the content of the stream
save.push(temp[0]);
}
if ((postfixExpr[i] >= '0') && (postfixExpr[i] <= '9'))
{
save.push(postfixExpr[i]);
}
}
cout << save.pop() <<" in module 10"<< endl;
return 1;
}

Find character in a string

I cant get the char search to work. The substring function is working but the char search won't provide the right location of the char it is looking for
#include<iostream>
#include <string>
using namespace std;
int charsearch(string searchInto, char ch, int start = 0)
{
int x = 0;
long n = searchInto.length();
for (int i = 1; i < n; i++)
{
cout << ch;
if (searchInto[i] == ch)
{
i = x;
}
else
i++;
}
cout<< x;
return x;
}
int substr(string src, string tosearch, int start = 0)
{
string searchInto = src;
long n = searchInto.size();
long m = tosearch.size();
int ans = -1;
for (int i = start; i < n; ++i)
{
int p = i;
int q = 0;
bool escape = false;
while (p < n && q < m) {
if (searchInto[p] == tosearch[q]) {
if (tosearch[q] == '/' && !escape) {
++q;
} else {
++p; ++q;
}
escape = false;
} else if (!escape && tosearch[q] == '*') {
++q;
while (q < m && p < n && searchInto[p] != tosearch[q]) ++p;
escape = false;
} else if (!escape && tosearch[q] == '?') {
++p; ++q;
escape = false;
} else if (tosearch[q] == '/' && !escape) {
escape = true;
++q;
} else break;
}
if (q == m) {
return i;
}
if (q == m - 1 && tosearch[q] == '*') {
if (q > 0 && tosearch[q - 1] == '/') continue;
else return i;
}
}
return ans;
}
int main()
{
string searchInto, tosearch;
cout<< "Enter string:";
getline(cin, searchInto);
cout << "Looking for :";
getline(cin, tosearch);
if (tosearch.length() < 2)
{
char ch = tosearch.at(0);
cout << "Found at: " <<charsearch(searchInto, ch) << endl;
cout << "Used Char" << endl;
}
else
cout << "Found at: " <<substr(searchInto, tosearch) << endl;
return 0;
}
To find a character in a string, you have two interfaces.
std::string::find will return the position of a character you find:
auto pos = yourStr.find('h');
char myChar = yourStr[pos];
If the character does not exist, then std::string::npos will be returned as the std::size_t returned for position.
stl algorithm std::find, in header algorithm returns an iterator:
auto it = std::find(yourStr.begin(), yourStr.end(), 'h');
char myChar = *it;
If the character does not exist, then it == yourStr.end().
There are some silly mistakes in your CharSearch method. First of all, You have to break the loop when you got your target character. And most importantly you are not assigning x when you are finding the target. Furthermore, there is extra increment of value i inside the loop. I have modified the function. Please check it below
int charsearch(string searchInto, char ch, int start = 0) {
int x = -1;
long n = searchInto.length();
for (int i = start; i < n; i++)
{
cout << ch;
if (searchInto[i] == ch)
{
x = i; // previously written as i = x which is wrong
break; // loop should break when you find the target
}
}
cout<< x;
return x;
}
Please note that,you can either also use find method of string or std::find of algorithm to search in string.
You need to make changes as per this code
int charsearch(string searchInto, char ch, int start = 0)
{
int x = -1; // : change, if return -1, means not found
long n = searchInto.length();
for (int i = start; i < n; i++) // : change
{
cout << ch;
if (searchInto[i] == ch)
{
x = i; // : change
break; // : change
}
}
cout<< x;
return x;
}
Note : This function will return 1st match.