code doesn't convert expression into rpn anymore - c++

code just turns infix to infix but I can't figure out why?, my code is supposed to turn infix to rpn but this line here:
while( !presedence.empty() && presedence.top() >= num2 )
{
output.push(oprators.top());
oprators.pop();
presedence.pop();
}
is the one that causes error, I think, because if I remove the '='
it just works, be it without allowing letters of the same precedence to join the output queue.
full code:
#include <cmath>
#include <stack>
#include<queue>
#include <iostream>
#include <regex>
#include <vector>
#include <thread>
#include <bitset>
#include <ctime>
#include <string.h>
#include <math.h>
#include <bits/stdc++.h>
#define M_PI 3.14159265358979323846264338327950288419716939937510582097494
#include<windows.h>
#define gkey GetAsyncKeyState
using namespace std;
#define rxs regex_search
#define loop while(true)
double a;
double num1;
double c3 = 299792458;
double c3sq = 89875517873681764;
int mc;
string again;
stack<int> presedence;
stack<string> oprators;
queue<double> numbers;
stack<char> test;
double num5;
double num6;
int E;
int abrt = 0;
double num2;
double ans = num1 + num2;
int num;
int numalt = 0;
int numaltt = 0;
//int nums [] = {srand(time(0));rand();}
bool autoregex(string test){
regex e ("[-+]?([0-9]*\.[0-9]+|[0-9]+)");
if (regex_match (test,e))
return true;
return false;
}
bool autrege(string test){
regex aret("SIN|LOG|sqrt|sin|log|tan|pi|e|ln|EE|[^0-9a-z$##&\]");
if (regex_match (test,aret)){
return true;
}
else{
return false;}
}
void namehere(string test){
if(autrege(test) == true){
regex bret("[+-]");
regex cret("[/*xX]");
regex dret("SIN|LOG|sqrt|sin|log|tan|pi|!|e|ln|EE|\\^");
regex omega("\\)");
regex canmae("\\(");
if (regex_match (test,bret)){num2 = 1;};
if (regex_match (test,cret)){num2 = 2;};
if (regex_match (test,dret)){num2 = 3;};
if (regex_match (test,omega)){num2 = 4;numaltt = numaltt + 1;};
if (regex_match (test,canmae)){num2 = 4;numalt = numalt + 1;};
}
}
int main()
{
vector<double> vec;
again = "n";
while(again == "n"&&abrt == 0){
// queue<double> numbers; stack<int> pres;
queue<string> output;
int test;
string name;
getline(cin, name);
istringstream iss(name);
string token;
while(iss >> token)
{
if(autoregex(token) == true){
output.push(token);
}
if(autrege(token)== true)//token area
{
namehere(token);
num6++;
if(num2 == -1){cout<<"wrong move: ";again = "n";again = "y";cout<<num2<<endl;}
while(presedence.empty() == 1 && oprators.empty() == 1)
{
presedence.push(num2);
oprators.push(token);
}
while(presedence.top() < num2 && !presedence.empty())
{
oprators.push(token);
presedence.push(num2);
}
while(presedence.top() >= num2 && !presedence.empty())
{
output.push(oprators.top());
oprators.pop();
presedence.pop();
}
//3-T 2-ME
}
}
while(presedence.empty() != 1 && oprators.empty() != 1){ output.push(oprators.top());
oprators.pop();presedence.pop();}
while(!output.empty()){cout<<output.front()<<", ";output.pop();}
}
while(again != "n"&&abrt == 0){
}
}
it breaks when I try to see if the top of the operator stack is greater than the current operator,any reasons?

NOTE: This answer refers to revision 2 of the question, which was about why OP's code was crashing. Meanwhile, OP has applied the fix mentioned in my answer (which seems to have fixed the crash), and has overwritten the question to address the next problem in the code. Therefore, this answer of mine no longer corresponds to the question in its current state.
The line
while(presedence.top() >= num2 && !presedence.empty())
is wrong. You should check whether the stack is empty before accessing the topmost element:
while( !presedence.empty() && presedence.top() >= num2 )
Otherwise, your program will be invoking undefined behavior if the stack is indeed empty.

Related

Check if every string in a set contains equal number of 'a' and 'b' okay I tried again will some one work something out now?

Will some one explain or make a program in c++ of this for me? Got assignment but don't know how to do it.
Question: You are given a set of strings which contain only as and bs, your program should be able to check whether each string has the same number of as and bs in it or not.
e.g. The program will respond true if it get {ab, aabb, aaabbbb, bbbaaa} and say false when it gets {aab, bbba, aaabbbb}
Solve it using stack
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
int count1 = 0;
int count2 = 0;
bool isInLanguageL (string w);
int main()
{
string input;
cout << "Input any string; ";
getline(cin,input);
if (input.length() % 2 != 0)
cout <<"Pattern entered does not match the language ";
else
isInLanguageL(input);
return 0;
}
bool isInLanguageL (string w)
{
stack<string> word1, word2;
string a, b;
for (unsigned i = 0; i < w.length()/2; i++)
{
a = w.at(i);
word1.push(a);
}
reverse(w.begin(), w.end());
for (unsigned i = 0; i < w.length()/2; i++)
{
b = w.at(i);
word2.push(b);
}
while(!word1.empty() && !word2.empty())
{
word1.pop();
count1 = count1++;
word2.pop();
count2 = count2++;
}
if(count1 == count2)
return true;
else
return false;
}
This solution is using stack, please refer to the comments written in the code. If you have any doubt you can comment them.
Code:
#include <iostream>
#include <stack>
#include <string>
using namespace std;
void checkString(string s) {
if (s.size() % 2 != 0) {
cout << "Doesn't satisfy the conditon\n";
return;
}
stack<char> st;
int n = s.size();
for (int i = 0; i < n; ++i) {
/*
case - 1 : If the stack is empty you can directly push the current character into the stack
case - 2 : If there are elements present in the stack, then if the current character is equal to the top character on the stack then we can push the current character
beacuse we didn't find any new character to match them.
*/
if (st.empty() || (st.top() == s[i])) {
st.push(s[i]);
}
/*
case-3 : If the stack is not emtpy and current character is different from the top character on the stack then we found a match like a-b (OR) b-a, so then we will
remove the top element from the stack and move to next character of the string
*/
else if (st.top() != s[i]) {
st.pop();
}
}
/*
case - 1 : After iterating through all the characters in the string, if we find the stack is emtpy then we can say all characters are not matched
case - 2 : If stack is emtpy, then that means all the characters are matched.
*/
(st.empty()) ? (cout << "Yes, satisfies the conditon\n") : (cout << "Doesn't satisfy the conditon\n");
}
int main() {
string s = "";
cin >> s;
checkString(s);
return 0;
}
Your solution has a number of mistakes that you should probably solve by using a debugger. Here's a reference.
This solution doesn't use a stack as you asked for, but you can write this function that uses algorithms to solve your problem:
namespace rs = std::ranges;
bool all_equal_as_and_bs(auto const & strings)
{
return rs::all_of(strings, [](auto const & string)
{
return rs::count(string, 'a') == rs::count(string, 'b');
});
}
And use it like this:
all_equal_as_and_bs(std::vector<std::string>{"ab", "aabb", "aaabbb", "bbbaaa"}); // true
all_equal_as_and_bs(std::vector<std::string>{"aab", "bba", "aaabbbb", "bbbaaa"}); // false

Shunting-Yard Algorithm C++ Not Passing Correctly Between Methods?

I am tasked with writing a Shunting-Yard algorithm for use in my final project (a calculator). I have written the program the way that makes sense to me, however, I am not getting any output when calling the main algorithm function (toRPN). I believe this is an issue with passing the values between parse and toRPN because I have tested parse directly within main and it works fine, but when I try to do a print test in the toRPN function, it prints nothing. Could someone point me in the right direction?
Header:
#include <iostream>
#include <math.h>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
#ifndef SHUNTING_YARD_ALGORITHM_SHUNTINGYARD_H
#define SHUNTING_YARD_ALGORITHM_SHUNTINGYARD_H
class ShuntingYard {
public:
stack <string> stack;
vector <string> tokens;
queue <string> outputList;
vector <char> operators;
vector <int> precedence;
vector <char> associativity;
ShuntingYard ();
bool hasOnlyDigits(const string s);
int getPrecedence(const string s);
int getAssociativity(const char c);
vector<string> parse(const string input) const;
string mainAlgorithm(const string);
};
#endif //SHUNTING_YARD_ALGORITHM_SHUNTINGYARD_H
cpp:
#include "ShuntingYard.h"
#include <iostream>
#include <math.h>
#include <vector>
#include <stack>
#include <queue>
#include <sstream>
#include <numeric>
using namespace std;
stack <string> stack1;
queue <string> outputList;
vector <string> operators;
vector <int> precedence;
vector <char> associativity;
ShuntingYard::ShuntingYard () = default;
bool hasOnlyDigits(const string s){
return s.find_first_not_of( "0123456789" ) == string::npos;
}
int getPrecedence(const string s) {
for(int i = 0; i < operators.size(); i++) {
if (s == operators[i])
return precedence[i];
}
}
char getAssociativity(const string s) {
for(int i = 0; i < operators.size(); i++) {
if (s == operators[i])
return associativity[i];
}
}
vector<string> parse(const string input) {
// Parses the string by white space
istringstream ss(input);
vector <string> tokenVector;
// Fill vector with ss
for (string input; ss >> input;) {
tokenVector.push_back(input);
}
return tokenVector;
}
string toRPN(const string s) {
// Delimit string by white space and store in vector
vector <string> tokens = parse(s);
// Test print
for (int i = 0; i < tokens.size(); i ++)
cout << tokens[i];
//Change "rt" to "$" to be easily accessed
for (int i = 0; i < tokens.size(); i ++) {
if (tokens[i] == "rt")
tokens[i] = "$";
}
// Stores operators and their precedence/associativity to vectors using same index
operators.push_back("+"); precedence.push_back(2); associativity.push_back('L');
operators.push_back("-"); precedence.push_back(2); associativity.push_back('L');
operators.push_back("/"); precedence.push_back(3); associativity.push_back('L');
operators.push_back("*"); precedence.push_back(3); associativity.push_back('L');
operators.push_back("^"); precedence.push_back(4); associativity.push_back('R');
operators.push_back("$"); precedence.push_back(4); associativity.push_back('R');
// Shunting-Yard logic
while (tokens.size() != 0) {
for (int i = 0; i < tokens.size(); i++) {
if (hasOnlyDigits(tokens[i]))
outputList.push(tokens[i]);
if ( find(operators.begin(), operators.end(), tokens[i]) != operators.end()) {
while (getPrecedence(stack1.top()) > getPrecedence(tokens[i]) || (getPrecedence(stack1.top()) == getPrecedence(tokens[i]) &&
getAssociativity(tokens[i]) == 'L') && stack1.top() != "(") {
outputList.push(stack1.top());
stack1.pop();
stack1.push(tokens[i]);
}
}
if (tokens[i] == "(")
stack1.push(tokens[i]);
if (tokens[i] == ")")
while(!stack1.empty() && stack1.top() != "(") {
outputList.push(stack1.top());
stack1.pop();
}
stack1.pop();
}
if (tokens.size() == 0) {
while(!stack1.empty()) {
outputList.push(stack1.top());
stack1.pop();
}
}
}
// Replaces values with "$" back to "rt"
string str;
while (!outputList.empty()) {
if (outputList.front() == "$") {
str.insert(0,"rt");
outputList.pop();
}
else {
str.insert(0, (outputList.front()));
outputList.pop();
}
}
return str;
}
int main() {
string s1 = "3 + 4";
cout << toRPN(s1);
}
Update:
I have narrowed the issue down to the following while loop:
while (getPrecedence(stack1.top()) > getPrecedence(tokens[i]) || (getPrecedence(stack1.top()) == getPrecedence(tokens[i]) &&
getAssociativity(tokens[i]) == 'L') && stack1.top() != "(") {
outputList.push(stack1.top());
stack1.pop();
stack1.push(tokens[i]);
}
The line getPrecedence(stack1.top() > getPrecedence(tokens[I]) is the issue. In particular, running getPrecedence on the stack1.top(). This function basically takes in a string and compares it to the vector holding all of the operators that are stored. When it finds the index, it returns the precedence at that index (they are set up with all the indices in order). I don't see why I can't call this function in this way. The stack1.top() will just give a string which would be passed through and compared. Any thoughts?
Figured it out. There were a few things going one, but the main one which was haunting the program was that I was popping things off the stack when I shouldn't, resulting in the stack being empty, so it would never get into
while (getPrecedence(stack1.top()) > getPrecedence(tokens[i]) || (getPrecedence(stack1.top()) == getPrecedence(tokens[i]) &&
getAssociativity(tokens[i]) == 'L') && stack1.top() != "(")

Checking if alphabetic string is a palindrome in C++

I've attempted to write a code that checks whether or not a string is a palindrome. Here is the code:
#include <iostream>
#include <string>
using namespace std;
bool pal(string str)//This block of code checks if input string is a palindrome
{
bool valid;
int i;
for (i = 0; i < str.length(); i++)
{
if (str[-i] == str[i])
{
valid = true;
}
else
{
valid = false;
}
}
return valid;
}
int main()
{
string s;
cin >> s;
if (!pal(s))
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
}
return 0;
}
Currently I am getting "Debug Assertion Fail" error.
str[-i] == str[i]
is a problem since negative indices are not valid indices in C++.
You need to change the strategy a little bit.
bool pal(string str)
{
int i = 0;
int j = str.length() - 1;
for ( ; i < j; ++i, --j)
{
if (str[i] != str[j])
{
// No need for any more checks.
return false;
}
}
// If we come here, the string is a palindrome.
return true;
}
C++ Provides us with an inbuilt function reverse() which can be used to reverse the Input string and compare it with un reversed string and print the output. The code goes as follows.
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string str;
cin>> str;
string rev;
rev = str;
reverse(str.begin(), str.end()); // string reverse operation
if(rev == str){
cout<<"YES"<<endl; // Prints "Yes" if string is palindrome
}else{
cout<<"NO"<<endl; // Prints "No" if string is not palindrome
}
return 0;
}

How to make recursive function, it needs to check if in a given string the current letter and the one next to it is either lowercase or upper case?

It should convert a string like this: Example: HEloOO, should be converted into : heLOoo . For some reason it doesn't work,it just wont convert the letters from uppercase to lowercase and vice versa any help would be appreciated ?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void rek(char array[], int d)
{
int counter=0;
if(d==0)
{
printf("%s \n",array);
printf("%d \n",counter);
}
else
{
if((array[d]>='A' && array[d]<='Z')&&(array[d-1]>='A' && array[d-1]<='Z'))
{
array[d]=array[d]+32;
array[d-1]=array[d-1]+32;
counter++;
rek(array,d-2);
}
if((array[d]>='a' && array[d]<='z')&&(array[d-1]>='a' && array[d-1]<='z'))
{
array[d]=array[d]-32;
array[d-1]=array[d-1]-32;
counter++;
rek(array,d-2);
}
}
}
int main()
{
char array[100];
int d;
gets(array);
d=strlen(array);
rek(array,d);
return 0;
}
Your function does not call itself when two adjacent characters have different cases. Also you can get different results when the string is processed from the start or from the end.
I would write the function the following way
#include <stdio.h>
#include <ctype.h>
char * rek(char *s)
{
if (s[0] && s[1])
{
size_t i = 1;
if (islower((unsigned char)s[0]) && islower((unsigned char)s[1]))
{
s[0] = toupper((unsigned char)s[0]);
s[1] = toupper((unsigned char)s[1]);
++i;
}
else if (isupper((unsigned char)s[0]) && isupper((unsigned char)s[1]))
{
s[0] = tolower((unsigned char)s[0]);
s[1] = tolower((unsigned char)s[1]);
++i;
}
rek(s + i);
}
return s;
}
int main( void )
{
char s[] = "HEloOO";
puts(rek(s));
return 0;
}
The program output is
heLOoo
The main problem is that you recur only if your have a pair of upper-case or lower-case letters. Otherwise, you drop off the end of your if, return to the calling program, and quit converting things.
The initial problem is that you've indexed your string with the length. A string with 6 characters has indices 0-5, but you've started with locations 5 and 6 -- the final 'O' and the null character.
The result is that you check 'O' and '\0'; the latter isn't alphabetic at all, so you drop through all of your logic without doing anything, return to the main program, and finish.
For future reference, Here's the debugging instrumentation I used. Also see the canonical SO debug help.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void rek(char array[], int d)
{
int counter=0;
printf("ENTER rek %s %d\n", array, d);
if(d==0)
{
printf("%s \n",array);
printf("%d \n",counter);
}
else
{
printf("TRACE 1: %d %c%c\n", d, array[d-1], array[d]);
if((array[d]>='A' && array[d]<='Z')&&(array[d-1]>='A' && array[d-1]<='Z'))
{
printf("TRACE 2: upper case");
array[d]=array[d]+32;
array[d-1]=array[d-1]+32;
counter++;
rek(array,d-2);
}
if((array[d]>='a' && array[d]<='z')&&(array[d-1]>='a' && array[d-1]<='z'))
{
printf("TRACE 3: lower case");
array[d]=array[d]-32;
array[d-1]=array[d-1]-32;
counter++;
rek(array,d-2);
}
}
}
int main()
{
char *array;
int d;
array = "HEloOO";
d=strlen(array);
rek(array,d);
printf("%s\n", array);
return 0;
}
I come up with this dirty solution:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string solve(const string& str)
{
if (str.empty()) {
return "";
}
if (str.front() >= 'a' && str.front() <= 'z') {
return (char)toupper(str.front()) + solve(str.substr(1));
}
if (str.front() >= 'A' && str.front() <= 'Z') {
return (char)tolower(str.front()) + solve(str.substr(1));
}
}
int main()
{
string str;
cin >> str;
cout << solve(str) << endl;
return 0;
}

Testing if a string is a number or character [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to determine if a string is a number with C++?
I have written a very simple calculator program in C++. Here it is:
#include <iostream>
#include <string>
using namespace std;
int main()
{
double num1;
double num2;
string op;
double num3;
int x;
bool y = false;
do
{
cout<<"Press t to terminate the application"<<endl;
cout<<"Enter the first number"<<endl;
cin>>num1;
cout<<"Enter the operator"<<endl;
cin>>op;
cout<<"Enter the next number"<<endl;
cin>>num2;
if(op=="/"&&num2==0)
{
cout<<"You are attempting to divide by 0. This is impossible and causes the destruction of the universe. However, the answer is infinity"<<endl;
y = true;
}
if(y==false)
{
if(op=="+") {
num3 = num1+num2;
}
else if(op=="-") {
num3 = num1-num2;
}
else if(op=="*"||op=="x"||op=="X") {
num3 = num1*num2;
}
else {
num3 = num1/num2;
}
cout<<endl;
cout<<endl;
cout<<"Answer:"<<num3<<endl<<endl;
}
} while(x!=12);
return 0;
}
As you can see, I want to allow people to terminate the application by pressing 't'. This obviously won't work because cin will try and assign a letter to a double (if I do press 't' the application crashes). I am planning to use strings instead to get the input, but how would I test if the string is a letter or a number?
#include <cctype>
and use isalhpa(), isdigit(), isalnum() on string contents?
Here is sample and working code, just change it so it suits your needs
#include <iostream>
#include <string>
#include <cctype>
#include <stdlib.h>
using namespace std;
bool isNum(char *s) {
int i = 0, flag;
while(s[i]){
//if there is a letter in a string then string is not a number
if(isalpha(s[i])){
flag = 0;
break;
}
else flag = 1;
i++;
}
if (flag == 1) return true;
else return false;
}
int main(){
char stingnum1[80], stringnum2[80];
double doublenum1, doublenum2;
cin>>stingnum1>>stringnum2;
if(isNum(stingnum1) && isNum(stringnum2)){
doublenum1 = atof(stingnum1);
doublenum2 = atof(stringnum2);
cout<<doublenum1 + doublenum2 << endl;
}
else cout<<"error";
return 0;
}
You can input into a string, and then use the following function:
int atoi ( const char * str );
If the string is numerical it will translate it into an integer.
If the string isn't numerical it will return 0: in which case you can check only the first character of the string, if its a zero then consider the input as a 0. If the first character isn't a zero consider the string as not numeric.
Well if you only check for 't' you can do it stupid and easy way.
if(stringnum1== 't' || stringnum2== 't') {
//terminate
}
else {
doublenum1 = atof(stringnum1)
doublenum2 = atof(stringnum1)
// your math operations
}
Better way would be:
if(isalhpa(stringnum1) || isalpha(stringnum2)){
//terminate
}
else {
doublenum1 = atof(stringnum1)
doublenum2 = atof(stringnum2)
// your math operations
}
P.S.
if you want to test string and not char, here is sample: link the best way would be to make function to test if given string is number or not if it is number return true, else return false (or other way around)