C++ Stack Implementation (not working right) - c++

Here's the previous thread where I got help with this same lab. My stack is misbehaving, to say the least, when I add an item to stack, to print out later, it doesn't seem to add right. I always print out plus'(+), not matter if I enter another operand(*,/,+).
I am using a stack to convert a, user inputed, infix express to postfix. It seems to work fine except printing out the operands in the stack at the end.
#include <iostream>;
#include <vector>
using namespace std;
class DishWell{
public:
char ReturnFront(){
return Well.front();
}
void Push(char x){
Well.push_back(x);
}
void Pop(){
Well.pop_back();
}
bool IsEmpty(){
return Well.empty();
}
private:
vector<char> Well;
};
bool Precidence(char Input, char Stack){
int InputPrecidence,StackPrecidence;
switch (Input){
case '*':
InputPrecidence = 4;
break;
case '/':
InputPrecidence = 4;
break;
case '+':
InputPrecidence = 3;
break;
case '-':
InputPrecidence = 3;
break;
case '(':
InputPrecidence = 2;
break;
default:
InputPrecidence = 0;
}
switch (Stack){
case '*':
StackPrecidence = 4;
break;
case '/':
StackPrecidence = 4;
break;
case '+':
StackPrecidence = 3;
break;
case '-':
StackPrecidence = 3;
break;
case '(':
StackPrecidence = 2;
break;
default:
StackPrecidence = 0;
}
if(InputPrecidence>StackPrecidence) return true;
else return false;
}
int main(int argc, char** argv) {
DishWell DishTray;
char Input;
bool InputFlag;
InputFlag = true;
cout<<"Enter Input, invalid input will terminate"<<endl;
while(InputFlag){
cout<<"Input: ";
cin>>Input;
cout<<endl;
if((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||Input>='0'&&Input<='9')))//If Digit or Number
cout<<Input;
if((Input=='*'||Input=='/'||Input=='+'||Input=='-')){//if operand
if(DishTray.IsEmpty())
DishTray.Push(Input);
else if(Precidence(Input,DishTray.ReturnFront()))
DishTray.Push(Input);
else if(!Precidence(Input,DishTray.ReturnFront()))
cout<<"Output: "<<Input<<endl;
}
else if(!((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||(Input>='0'&&Input<='9')))||((Input=='*'||Input=='/'||Input=='+'||Input=='-')))//if not digit/numer or operand
InputFlag = false;
}
int counter = 0;
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnFront()<<endl;
DishTray.Pop();
}
return 0;
Thank you, Macaire Bell

Your loop calls front(), but then calls pop_back(). This will always return the first element in the vector, until all elements are popped, since you are never erasing the front element. Your ReturnFront() method should probably be:
char ReturnBack(){
return Well.back();
}
And then your loop at the end:
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnBack()<<endl; // will return last element
DishTray.Pop(); // actually pop the element printed
}

When you're working with a stack, you usually want to be able to see the value on the top of the stack. Your class only allows the very first item pushed (i.e. the bottom of the stack) to be visible. Your ReturnFront() should probably return Well.back() and perhaps it should be called something like ReturnTop().

Wouldn't you want to see the value returned from pop_back() instead if discarding it as you're currently doing?

Related

How to build the simple change maker for a vending machine?

On the menu deposits n,d, q, o,f are indicated which are indication for nickel dime quarter , one dollar and five dollar. I should also indicate "C" as in cancel option when the user hits c. But i couldn't make it work. My program still runs even the user hit c. I am confused on this point?
switch(DepositIndication) {
case 'n': {
PurchasedPrice=PurchasedPrice-0.05;
NumOfNickels=NumOfNickels+1;
}
break;
case 'd': {
PurchasedPrice=PurchasedPrice-0.10;
NumOfdimes=NumOfdimes+1;
}
break;
case 'q': {
PurchasedPrice=PurchasedPrice-0.25;
NumOfquarters=NumOfquarters+1;
}
break;
case 'o': {
PurchasedPrice=PurchasedPrice-1.00;
NumOfOnes=NumOfOnes+1;
}
break;
case 'f': {
PurchasedPrice=PurchasedPrice-5.00;
NumOfFives=NumOfFives+1;
}
break;
}
the condition c is missing and I Put the break into to brackets;
switch (DepositIndication) {
case 'n':
{
PurchasedPrice = PurchasedPrice - 0.05;
NumOfNickels = NumOfNickels + 1;
break;
}
case 'd':
{
PurchasedPrice = PurchasedPrice - 0.10;
NumOfdimes = NumOfdimes + 1;
break;
}
case 'q':
{
PurchasedPrice = PurchasedPrice - 0.25;
NumOfquarters = NumOfquarters + 1;
break;
}
case 'o':
{
PurchasedPrice = PurchasedPrice - 1.00;
NumOfOnes = NumOfOnes + 1;
break;
}
case 'f':
{
PurchasedPrice = PurchasedPrice - 5.00;
NumOfFives = NumOfFives + 1;
break;
}
case 'c':
}
//you can print cancellation messages in here
break;
}
default:
break;
}
I should also indicate "C" as in cancel option when the user hits c
Your current code works fine the only thing you are missing to make that work right now is a default case or a case where you specifically check if the user inputed C.
Example:
switch(DepositIndication) {
// All other cases ...
case 'c': {
// The user canceled the interaction
std::cout << "Interaction was canceled." << std::endl;
break;
}
// Default case to ensure that even,
// if the user hits any other key we still handle his interaction
default {
std::cout << "No fitting interactional behaviour found." << std::endl;
break;
}
}
If you want to ensure that the user can even input big lettered chars and the switch case will still work you can use std::tolower and cast it back to a char.
Make the User-Input lowercase:
// Make DepositIndication lowercase
DepositIndication = std::tolower(DepositIndication, std::locale());

Explain what this c++ bool line mean in this cpp book

playpen pp;
bool more(true);
do{
display_content();
int const choice(get_choice));
more = do_choice(pp, choice);
} while (more)
function code >>
bool do_choice(int choice){
bool more(true);
switch(choice){
case 0:
clear_playpen(???);
break;
case 1:
more = false;
break;
case 2:
change_plotmode(???);
break;
case 3:
plot_pixel(???);
break;
case 4:
change_scale(???);
break;
default:
throw problem("Not a valid option");
}
return more;
}
the do_choice function has a declaration bool do_choice(int choice);
with the last line in definition as return true to the bool type. Why will the author again in the cpp script above say more = do_choice(...) which I am understanding to mean true = true // what use is that? Sounds gibberish to me
You're confusing the assignment operator (=) with the comparison operator (==).
The call to do_choice updates more so the loop will stop eventually.

C++ Boggle Solver Issues

void scoreBoardHelper(Grid<char>& board, Lexicon& lex, Set<string>& visitedPrefixes, string current, GridLocation location, Set<string>& foundWords, Set<GridLocation> visitedTiles){
if(lex.contains(current) && current.size()>3){
foundWords.add(current);
}
if(current == ""){
current += board[location];
visitedTiles.add(location);
}
//check neighbors
GridLocation neighbor = location;
for(int i = 0; i<8; i++){
switch (i) {
case 0:
neighbor.col++;
break;
case 1:
neighbor.col--;
break;
case 2:
neighbor.row++;
break;
case 3:
neighbor.row--;
break;
case 4:
neighbor.col++;
neighbor.row++;
break;
case 5:
neighbor.col--;
neighbor.row--;
break;
case 6:
neighbor.col--;
neighbor.row++;
break;
case 7:
neighbor.col++;
neighbor.row--;
break;
}
if(board.inBounds(neighbor) && board[neighbor]!=current[current.size()-2] && !visitedTiles.contains(neighbor) && lex.containsPrefix(current + board[neighbor]) && !visitedPrefixes.contains(current + board[neighbor])){
visitedPrefixes.add(current + board[neighbor]);
visitedTiles.add(neighbor);
scoreBoardHelper(board, lex, visitedPrefixes, current + board[neighbor], neighbor, foundWords, visitedTiles);
}
neighbor = location;
}
}
int scoreBoard(Grid<char>& board, Lexicon& lex) {
Set<string> visitedPrefixes;
Set<GridLocation> visitedTiles;
string current = "";
GridLocation location;
Set<string> foundWords;
for(int r=0;r<board.numRows();r++){
location.row=r;
for(int c=0;c<board.numCols();c++){
location.col=c;
scoreBoardHelper(board, lex, visitedPrefixes, current, location, foundWords, visitedTiles);
}
}
int previousPoints = 0;
for(string word : foundWords){
cout<<"found word: "<<word<<endl;
previousPoints += points(word);
}
return previousPoints;
}
I wrote these 2 functions but they don't seem to solve boggle. When I remove the !visitedTiles.contains(neighbor) check, it works as expected but it finds extra words that it should discard. When it has this check it narrows the solution unexpectedly and finds 2 words where it should find many more. Note: The points function works fine.

Reverse Polish notation Calculator

I am currently working on a RPN calculator, it takes an infix expression converts it to postfix and shows the answer. I mostly got it right, but when I pop the answer from the stack if shows only the last digit of the result
ex
Enter infix: (1+1)*13+10/2
Postfix: 11+13*102/+
Result is: 1
Enter infix: 2*13+10/2
Postfix: 213*102/+
Result is:1
It gets it right for this kind of inputs
Enter infix: 3*2+5
Postfix: 32*5+
Result is : 11
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
class infix2postfix
{
public:
void push(int symbol);
int pop();
void infix_to_postfix();
int priority(char symbol);
int isEmpty();
int white_space(char);
int eval_post();
};
char infix[100], postfix[100];
int stack[100];
int top;
int main()
{
infix2postfix ip;
top=-1;
cout<<"Enter infix : ";
gets(infix);
ip.infix_to_postfix();
cout<<"Postfix : "<<postfix<<endl;
cout<<"Result is : "<<ip.eval_post()<<endl;
return 1;
}
void infix2postfix :: infix_to_postfix()
{
int i,p=0;
char next;
char symbol;
for(i=0; i<strlen(infix); i++)
{
symbol=infix[i];
if(!white_space(symbol))
{
switch(symbol)
{
case '(':
push(symbol);
break;
case ')':
while((next=pop())!='(')
postfix[p++] = next;
break;
case '+':
case '-':
case '*':
case '/':
case '%':
case '^':
while( !isEmpty( ) && priority(stack[top])>= priority(symbol) )
postfix[p++]=pop();
push(symbol);
break;
default: /*if an operand comes*/
postfix[p++]=symbol;
}
}
}
while(!isEmpty( ))
postfix[p++]=pop();
postfix[p]='\0'; /*End postfix with'\0' to make it a string*/
}
/*This function returns the priority of the operator*/
int infix2postfix :: priority(char symbol)
{
switch(symbol)
{
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
case '%':
return 2;
case '^':
return 3;
default :
return 0;
}
}
void infix2postfix :: push(int symbol)
{
if(top>100)
{
cout<<"Stack overflow\n";
exit(1);
}
stack[++top]=symbol;
}
int infix2postfix :: pop()
{
if( isEmpty() )
{
cout<<"Stack underflow\n";
exit(1);
}
return (stack[top--]);
}
int infix2postfix :: isEmpty()
{
if(top==-1)
return 1;
else
return 0;
}
int infix2postfix :: white_space(char symbol)
{
if( symbol == ' ' || symbol == '\t' )
return 1;
else
return 0;
}
int infix2postfix :: eval_post()
{
int a,b,i,temp,result;
for(i=0; i<strlen(postfix); i++)
{
if(postfix[i]<='9' && postfix[i]>='0')
push(postfix[i]-'0');
else
{
a=pop();
b=pop();
switch(postfix[i])
{
case '+':
temp=b+a;
break;
case '-':
temp=b-a;
break;
case '*':
temp=b*a;
break;
case '/':
temp=b/a;
break;
case '%':
temp=b%a;
break;
case '^':
temp=pow(b,a);
}
push(temp);
}
}
result=pop();
return result;
}
Consider what happens when eval_post() is given 213*102/+ to work with. Let's start in the middle, with the '1' after the asterisk. The '1' is a digit, so push it [stack ends with: 1]. Similarly, the 0 and 2 get pushed [stack ends with: 1, 0, 2]. Then the division symbol is encountered, so pop 2 and 0, then push 0/2 = 0 [stack ends with: 1, 0]. Finally, the addition symbol is encountered, so pop 0 and 1, then push 1+0=1, which is then popped as your answer.
One symptom of your problem is that, if things work, the stack should be empty when eval_post() returns. However, it is not empty when your infix includes numbers with more than one digit. Note that "10" gets pushed onto the stack as two numbers: "1" followed by "0". You want the value 10 pushed.
There are also some style problems with the code, but this appears to be the main functional problem.

C++ program crashes in the while loop when asked to use random number generator

So I am trying to make a program which will generate random basic mathematical questions like addition, subtraction, etc.
While I am trying to generate division questions I made a do-while loop which runs until the prerequisite is met for division quesions.
But for some reason when I ask it to generate 20 division questions with none with remainder it always crashes.
Please help
Here's the code
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int correct,total,MAXVAL;
const char oper[4]={'/','/','/','/'};
typedef struct data{
int first,second;
char operation;
}data;
data datagenerator(){
data newData;
newData.first= (rand()%MAXVAL);
newData.operation=oper[rand()%4];
newData.second=(rand()%MAXVAL);
return newData;
}
bool corrector(data newData){
bool isture=false;
switch(newData.operation){
case '/':
if((newData.first%newData.second)==0){
isture=true;
}
break;
case '*':
isture=true;
break;
case '+':
isture=true;
break;
case '-':
isture=true;
break;
}
return isture;
}
void quizer(){
system("CLS");
for(int counter=1;counter<=total;counter++){
cout<<"Q"<<counter<<": ";
data newData;
do{
newData=datagenerator();
}while(!corrector(newData));
cout<<newData.first<<newData.operation<<newData.second<<"\n";
}
cout<<"\nYou got "<<correct<<"/"<<total<<"correct\n";
}
int main(){
//srand((unsigned)time(0));
char x;
cout<<"How many questions do you want?"<<endl;
cin>>total;
cout<<"Enter the maximum value\n";
cin>>MAXVAL;
cout<<"Are you ready?\n";
cin>>x;
quizer();
system("PAUSE");
return 0;
}
You need to check for a division by 0.
bool corrector(data newData){
bool isture=false;
switch(newData.operation){
case '/':
if(newData.second == 0) {
break;
}
if((newData.first%newData.second)==0){
isture=true;
}
...
Your generating a 0 as a second number and then trying to use it to divide by a number.
you can put a check like this
if(newData.second == 0) {
return false;
}
Your problem lies right on line 17 and 19. You are dividing by 0, assuming you are setting the value on MAXVAL to 0 when it asks you. With modulo division you need to be careful with that.