I've written and modified an example code from a C++ book about pushing/popping numbers off a stack class. This is a basic question just for my understanding.. Here is the code.
//stakarray.cpp
//a stack as a class
#include <iostream>
using namespace std;
class Stack
{
private:
enum { MAX = 10 };
//int MAX=10;
int st[MAX];
int top;
public:
Stack()
{ top=0; }
void push(int var)
{ st[++top]=var; } //increments stack, input var
int pop()
{ return st[top--]; } //returns var, decrements stack
void show(int var)
{ cout << st[var]<< endl; }
};
int main()
{
//some stack operations
int i;
Stack s1;
s1.push(11);
s1.push(22);
cout<<"1: "<<s1.pop()<<endl; //22
cout<<"2: "<<s1.pop()<<endl; //11
s1.push(33);
s1.push(44);
s1.push(55);
s1.push(66);
for (i=0; i<= 10 ; i++)
{
cout<< "s1[" << i << "]= ";
s1.show(i);
}
return 0;
}
The output of this program gives
1: 22
2: 11
s1[0]= 2
s1[1]= 33
s1[2]= 44
s1[3]= 55
s1[4]= 66
s1[5]= 0
s1[6]= 0
s1[7]= 0
s1[8]= 4196896
s1[9]= 0
s1[10]= 4
Why is s1[0]=2, s1[8]=4196896, s1[10]=4? Is there also any way to access MAX from private or do i have to define it somewhere else in the class (not using as global variable or part of main())?
Element 0 is never used, because in push you use pre-increment (++top) instead of post-increment (top++).
Your stack has at most 4 elements in it at a time, therefore all elements following index 4 have undefined content (i.e., random garbage in s1[5]...s1[10]).
In your code you were incrementing top with a pre-increment ++top before setting the value. Therefore, top would go to 1 and then you would set s1[1]=33. If you switch to post-increment top++, your counter variable top will increment after setting s[0]=33.
//stakarray.cpp
//a stack as a class
#include <iostream>
using namespace std;
class Stack
{
private:
enum { MAX = 10 };
//int MAX=10;
int st[MAX];
int top;
public:
Stack()
{ top=0; }
void push(int var)
{ st[top++]=var; } //increments stack, input var
int pop()
{ return st[top--]; } //returns var, decrements stack
void show(int var)
{ cout << st[var]<< endl; }
};
int main()
{
//some stack operations
int i;
Stack s1;
s1.push(11);
s1.push(22);
cout<<"1: "<<s1.pop()<<endl; //22
cout<<"2: "<<s1.pop()<<endl; //11
s1.push(33);
s1.push(44);
s1.push(55);
s1.push(66);
for (i=0; i<= 10 ; i++)
{
cout<< "s1[" << i << "]= ";
s1.show(i);
}
return 0;
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
How come when I type a large number the output just repeasts itself over and over?
#include "stack.h"
#include <string>
#include <sstream>
#include <math.h>
using namespace std;
void convertBinaryToDecimal(string num, MyStack<int>& thestack);
int main() {
MyStack<int> thestack;
int input = -22222;
while (true) {
cout << "enter -999 to quit, Enter your binarty number: ";
cin >> input;
if (input == -999) {
cout << "Thank you, see you next time." << endl;
system("Pause");
break;
}
else {
string str = to_string(input);
convertBinaryToDecimal(str, thestack);
}
}
}
void convertBinaryToDecimal(string num, MyStack<int>& thestack) {
int remainder = 0;
int count = 0;
int dec_value = 0;
int n;
stringstream number(num);
number >> n;
while (n != 0) {
remainder = n % 10;
n /= 10;
dec_value += remainder * pow(2, count);
count++;
}
thestack.push(dec_value);
int value = thestack.top();
thestack.pop();
cout << "The equivalent decimal number is: " << value << endl;
}
.cpp file^
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
template<class Type>
class MyStack {
public:
int count;
MyStack(int mysize = 100) {
list = new int[mysize];
maxStackSize = mysize;
stackTop = 0;
count = 0;
}
MyStack(const MyStack<Type>& thestack) {
copyStack(thestack);
}
~MyStack() {
delete[] list;
}
void initializeStack();
bool isEmptyStack() const;
bool isFullStack() const;
Type push(const Type& newItem);
Type top()const;
void pop();
const MyStack<Type>& operator=(const MyStack<Type>& thestack) {
copyStack(thestack);
return *(this);
}
private:
int maxStackSize;
int stackTop;
Type* list;
void copyStack(const MyStack<Type>&);
};
template<class Type>
void MyStack<Type>::initializeStack() {
stackTop = 0;
}
template<class Type>
bool MyStack<Type>::isEmptyStack() const {
return (stackTop == 0);
}
template<class Type>
bool MyStack<Type>::isFullStack() const {
return (stackTop == maxStackSize);
}
template<class Type>
Type MyStack<Type>::push(const Type& newItem) {
if (isFullStack()) {
return NULL;
}
list[stackTop] = newItem;
stackTop++;
return list[stackTop - 1];
}
template<class Type>
Type MyStack<Type>::top()const {
if (isEmptyStack()) {
return NULL;
}
return list[stackTop - 1];
}
template<class Type>
void MyStack<Type>::pop() {
if (isEmptyStack()) {
}
else {
stackTop--;
}
}
template<class Type>
void MyStack<Type>::copyStack(const MyStack<Type>& thestack) {
delete[] list;
list = new Type[thestack.maxStackSize];
for (int i = 0; i < thestack.maxStackSize; i++) {
list[i] = thestack.list[i];
}
stackTop = thestack.stackTop;
maxStackSize = thestack.maxStackSize;
}
#endif//STACK_H_INCLUDED
header file^
When I type a large binary like "101010100100101010" the output repeats itself over and over. When I type a smaller binary like "1010" it's fine and gives me the correct output.
Any ideas? I am pretty sure it just crashes.
Edit: I've been testing it and it breaks after 10 digits.
Hm. I think the main problem ist that you are reading the binary number from a user into an int variable. So, if the the user enters 1000, you expect it to be 8, but in reality it is 1000(decimal). Then you convert 1000(decimal) into a string, which is then "1000". That is of course not good and one cause of your problem.
Integer variables can hold values up to a given boundary. You can find out in C++ using
#include <limits>
#include <iostream>
int main()
{
std::cout << std::numeric_limits<int>::max() << "\n";
return 0;
}
The result is machine dependent. A possible value is on a 32bit hardware is: 2147483647
So, now you enter a big string of '1's and '0's, e.g. "101010100100101010" And you expect to read a binary. But you try to put it in an integer. But the decimal number 101010100100101010 will not fit into an integer and so your complete intended functionality will not work as you expect.
The solution is to read the value from the user into a std::string and not into an int
Then you can convert the binary data in the std::string into a decimal.
For that you can use existing build in functions like:
#include <string>
#include <iostream>
int main()
{
const std::string testBinary{"101010100100101010"};
std::cout << std::stoul(testBinary,0,2) << "\n";
return 0;
}
Or a simple conversion with iterating through the string:
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
const std::string testBinary{"101010100100101010"};
unsigned long decimalValue{0};
std::for_each(testBinary.rbegin(),testBinary.rend(), [&decimalValue] (const char& c) { decimalValue |= (c-'0'); decimalValue <<= 1; });
std::cout << decimalValue << "\n";
return 0;
}
The stack is not needed at all for this functionality. I am not sure, why you put it in. Maybe for academic purposes.
By the way, you can check for the correctness of a "binary string" with
if (std::all_of(testBinary.begin(), testBinary.end(), [](const char& c){ return c=='1' || c=='0';}))
In my program, I have a class that holds a vector of type integer. It is used to store distances. I have a function, that when called, should set values in the vector to 0's. (used for initializing). But when I go to check the size of the vector, it still says the vector is empty.
I have created multiple functions that check whether the vector is adding any elements, and it is not. I have a function, that within main, I call to see if the vector is empty, and it returns 0 (the vector has 0 elements in it).
int MLB::getDistanceSize()
{
return distances.size();
}
void MLB::setInitialDistances(int size)
{
for(int i = 0; i < size; i++)
{
this->distances.push_back(0);
}
}
class MLB
{
public:
//constructor
MLB();
~MLB();
int getDistanceSize();
void setInitialDistances(int size);
private:
vector<int> distances;
};
The input file is a csv file with each line consisting of:
stadium1,stadium2,distance
so sample input file is:
AT&T Park,Safeco Field,680
AT&T Park,Oakland–Alameda County Coliseum,50
Angel Stadium,Petco Park,110
Angel Stadium,Dodger Stadium,50
Busch Stadium,Minute Maid Park,680
Busch Stadium,Great American Ball Park,310
Busch Stadium,Target Field,465
Busch Stadium,Kauffman Stadium,235
etc...
I am using qt, and this is where I am calling the functions themselves. All information is stored into a map, and the other getters work perfectly fine. Sorry for making this a lot more confusing than the problem really is, any help is greatly appreciated.
// key and value, key is the team name, value is the MLB stadium information
struct entry
{
string key;
MLB value;
};
class Map
{
public:
//Public default constructor
Map();
//Public default destructor
~Map();
// returns entry of the map
entry atIndex(int index);
// Inserts a key and its value using linear algorithm
void insert(const string& theKey, const MLB& value);
private:
vector<entry> thisTable;
int currentSize; //Integer variable for current size
};
functions for Map:
Map::Map()
{
currentSize = 0;
}
Map::~Map()
{
}
void Map::insert(const string& theKey, const MLB& value)
{
entry thisEntry;
thisEntry.key = theKey;
thisEntry.value = value;
thisTable.push_back(thisEntry);
currentSize+=1;
}
entry Map::atIndex(int index)
{
return thisTable.at(index);
}
//mainwindow constructor
mainWindow::mainWindow()
{
//Reads in input from first csv file, all works fine all data stored and can access it
string iStadium1;
string iStadium2;
string iDistance;
string previous;
int distance;
int index1;
int index2;
bool found;
ifstream csvFile2;
csvFile2.open("inputDistance.csv");
getline(csvFile2, iStadium1, ',');
while(!csvFile2.eof())
{
index1 = 0;
found = false;
while(!found)
{
if(thisMap.atIndex(index1).value.getStadiumName() == iStadium1)
{
thisMap.atIndex(index1).value.setInitialDistances(thisMap.mapSize());
cout << "Distance Size Test 1: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
found = true;
}
else
{
index1++;
}
}
previous = iStadium1;
while(iStadium1 == previous)
{
getline(csvFile2, iStadium2, ',');
getline(csvFile2, iDistance, '\n');
distance = stoi(iDistance);
index2 = 0;
found = false;
while(!found)
{
if(thisMap.atIndex(index2).value.getStadiumName() == iStadium2)
{
found = true;
cout << "Distance Size Test 2: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
// crashes here. Index out of bounds, size is 0 for some reason
thisMap.atIndex(index1).value.setDistance(index2, distance);
}
else
{
index2++;
}
}
getline(csvFile2, iStadium1, ',');
}
}
csvFile2.close();
}
I expect the vector to hold 30 slots (assuming the desired size passed into the function is 30) of value 0, rather than having an empty vector.
The code in your question works as expected after adding constructor and destructor (doing both nothing) :
#include <iostream>
#include <vector>
using namespace std;
class MLB
{
public:
//constructor
MLB();
~MLB();
int getDistanceSize();
void setInitialDistances(int size);
private:
vector<int> distances;
};
int MLB::getDistanceSize()
{
return distances.size();
}
void MLB::setInitialDistances(int size)
{
for(int i = 0; i < size; i++)
{
this->distances.push_back(0);
}
}
MLB::MLB() {
}
MLB::~MLB() {
}
int main()
{
MLB mlb;
mlb.setInitialDistances(30);
cout << mlb.getDistanceSize() << endl;
}
pi#raspberrypi:/tmp $ g++ d.cc
pi#raspberrypi:/tmp $ ./a.out
30
the vector is not empty but contains 30 times 0
if thisMap.atIndex(index1).value.setDistance(index2, distance); does nothing this is probably because atIndex(index1) returns a copy rather than a reference, so you modify a copy and the original is unchanged
For instance :
#include <iostream>
#include <vector>
using namespace std;
class C {
public:
vector<int> getv() { return v; } // return a copy
vector<int> & getvref() { return v; } // return the ref to the vector, not a copy
int len() { return v.size(); }
private:
vector<int> v;
};
int main()
{
C c;
c.getv().push_back(0); // modify a copy of v
cout << c.len() << endl;
c.getvref().push_back(0); // modify v
cout << c.len() << endl;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ vv.cc
pi#raspberrypi:/tmp $ ./a.out
0
1
you edited you question and this is what I supposed :
entry Map::atIndex(int index)
{
return thisTable.at(index);
}
return a copy, must be
entry & Map::atIndex(int index)
{
return thisTable.at(index);
}
#include<iostream>
using namespace std;
class ulam
{
int num;
double prod;
int cot;
public:
ulam(){cot=0;}
ulam(int x)
{
num=x;
}
void process()
{
for(int i=0;num==1;i++)
{
cout<<num<<endl;
if((num%2) == 0)
{
prod=num/2;
}
else
{
prod=(3*num)+1;
}
num=prod;
cot++;
}
}
void display()
{
cout<<"the number of steps required is: "<<cot;
}
};
int main()
{
int n;
cout<<"enter the number"<<endl;
cin>>n;
ulam obj(n);
obj.process();
obj.display();
}
when i write this code the cot value comes as a garbage value i think. i cant figure out where i went wrong. i used class because i feel it is more discriptive . but the main aim behind this program is to find the number of steps it is required for a number to reach one and to print the whole sequence of numbers. for thos who dont know about the collatz conjecture https://en.wikipedia.org/wiki/Collatz_conjecture
Your condition of the for loop inside process function is wrong. it should be num!=1. You need to initialize cot too. You don't need prod actually.
#include<iostream>
using namespace std;
class ulam
{
int num;
int cot;
public:
ulam()
{
cot=0;
}
ulam(int x)
{
cot=0;
num=x;
}
void process()
{
for(int i=0;num!=1;i++)
{
cout<<num<<endl;
if((num%2) == 0)
{
num=num/2;
}
else
{
num=(3*num)+1;
}
cot++;
}
}
void display()
{
cout<<"the number of steps required is: "<<cot;
}
};
int main()
{
int n;
cout<<"enter the number"<<endl;
cin>>n;
ulam obj(n);
obj.process();
obj.display();
return 0;
}
First Problem
In the constructor where you initialize when an integer is passed, you ALSO have to initialize cot like this:
ulam(int x)
{
cot = 0;
num = x;
}
Better yet, since cot is always going to be 0 at construction, just set cot to 0 as a private variable like this:
class ulam
{
int num;
double prod;
int cot = 0;
public:
//....
};
This means that you could still have a default constructor that will do nothing, and the one that takes an integer won't require cot to be set to 0.
Second Problem
Your second problem is that the loop condition is wrong. It should be num != 1, not num == 1. num == 1 would be the loop would never run unless 1 was passed in cin.
#include <iostream>
#include <string.h>
using namespace std;
#define NMAX 10 // pre-processing directive
template<typename T>
class Stack {
public:
T Smain, Saux;
T stackArray[NMAX];
int topLevel;
int getTopLevel()
{
return this->topLevel;
}
void push(T x)
{
if (topLevel >= NMAX - 1)
{
cout<<"The stack is full: we have already NMAX elements!\n";
return;
}
stackArray[++topLevel] = x;
}
int isEmpty()
{
return (topLevel < 0);
}
T pop()
{
if (isEmpty()) {
cout<<"The stack is empty! \n";
T x;
return x;
}
return stackArray[topLevel--];
}
T peek()
{
if (isEmpty())
{
cout<<"The stack is empty! \n";
T x;
return x;
}
return stackArray[topLevel];
}
void afficher() {
cout<<"On affiche la pile:";
for ( int i=0; i<=topLevel; i++ )
cout<<stackArray[i]<<" ";
cout<<endl;
}
Stack()
{
topLevel = -1;
}
~Stack() {
}
void change(int i)
{
while (Smain.topLevel>i){
Saux.push(Smain.pop());}
T aux1=Smain.pop();
T aux2=Smain.pop();
Smain.push(aux1);
Smain.push(aux2);
while (Saux.topLevel>=0){
Smain.push(Saux.pop());}
}
};
int main()
{
Stack<int> stack1;
Stack<int> stack2;
stack1.push(1);
stack1.push(2);
stack1.push(3);
stack1.push(4);
change(3);
stack1.afficher();
return 0;
}
This program has to swap the i and i-1 position of a stack, but i get the error: 'change' was not declared in this scope and i don't know how to make it work. please help me and thanks to you in advance.
change is declared inside the class Stack, so it becomes a method on a Stack instance.
You probably want to call it as stack1.change(3) instead.
You cannot call change() function which is inside a class directly.instead use an class object to call it.
class stack{
}objectname;
int main(){
objectname.change(3);
}
I'm trying to create an array of size 100 filled with 0's. When I go to print out the area what prints is: 0x7fff5fbff54c. It seems to be printing out the address of the area and I am not sure why and how I should fix this so that it prints out what it is supposed to. Below is my code.
List.hpp
typedef int ElementType;
const int MAX = 100;
class List
{
public:
List();
bool Empty();
void InsertAtEnd(ElementType x);
void Delete(ElementType x);
void Display();
int Smallest();
int Largest();
int Range();
private:
int N;
ElementType listArray[MAX];
};
List.cpp
#include "List.hpp"
#include <iostream>
using namespace std;
List::List() {
listArray[99] = {0};
}
void List::Display() {
cout << listArray;
}
main.cpp
#include "List.hpp"
#include <iostream>
using namespace std;
int main() {
List list;
list.Display();
return 0;
}
That is because listArray is a pointer, you are printing the address of the pointer.. If you want to print the content you need to write a loop that will iterate through each element and print the values.
something like:
for (int i=0; i< MAX; ++i)
{
cout << listArray[i] << ", ";
}
cout << endl;
#πάνταῥεῖ is correct. Try this instead:
class List
{
public:
List();
bool Empty();
void InsertAtEnd(ElementType x);
void Delete(ElementType x);
void Display();
int Smallest();
int Largest();
int Range();
private:
int N;
ElementType listArray[MAX] = {0};
};
And remove the initialization from your constructor
Wouldn't you want a loop:
see this previous question:
loop through an array in c++
The code you have
List::List() {
listArray[99] = {0};
}
Just initializes the value of your listArray at index 99.
To initialize your array with all values as 0 you need to use the constructors initializer list:
List::List() : listArray {0} {
}