Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Stack that can handle both strings and floats in the same class??

Status
Not open for further replies.

hunternjb

Programmer
Mar 21, 2001
7
US
I am having a problem trying to come up with a way to build a stack that can handle both strings and floats in the same class. I am assuming a max of 5 elements in the stack to start with. I am also trying to avoid using malloc() and new when declaring the string, and using fixed arrays instead. Below is what I am pushing to the stack.

s.push( 1.0 );
s.push( 2 );
s.push( "three" );
s.push( 4 );
s.push( "FIVE" );
s.push( 6.6);

cout << s.pop() << endl;

I can't figure out a way to do this. Can someone please help me. Thanks.
 
Hi,

Yeah you can do that .. see this design.

The element of stack should be an union of an int, float and char array. Depending upon the data to be used, use corresponding element from union.

say union u{
int i;
float f;
char array[5];
}stackelement;

Now, write multiple push function with different signatures like
push(int)
push(float)
push(char *)

and use corresponding element.

i hope this is clear. Yeah, one problem is &quot;how to know which element at the time of popping up the element&quot;

regards,
Mahesh
 
when pushing the element, use a flag in the struct and set it when inside the pop function for float, use 1, for string use 2, for int is 3. then when poping, check the flag, and pop accordingly

 
in other words


struct node
{
int flag;
float a;
int b;
string c;
};

void stack::pop()
{
int temp = data[sp]->flag;
switch (temp)
{
case 1:
popfloat();
break;
case 2:
popstring();
break;
case 3:
popstring(); break; }
}

though, how would you get it back to the main program in which pop was called?

i guess the only way would be a reference or a pointer, but you wouldn't know which pointer type to send..

unless, make everything a string, and then parse it into floats, ints, when you need to use them that way.

this isn't so easy..

 
The pop() generally doesn't return a value, the top() does, which could return the union item, and the union could have functions that return bools and the flag (as an enumeration perhaps) for each item.

union stackclass::top()
{
return *top; //assuming you have a iterator or pointer
//top that always points the top of the stack
}
 
what about implementing a stack with a node type like this

struct nodetype
{
float blah;
int blah;
string blah;
int flag;
nodetype *back;
nodetype *forward;
}

so essentially build a doublylinked list, and call functions with a pointer to the type you want to get, and a flag to tell it what your looking for, and your function(s) could search for the first instance in the list that has a flag at the value your searching for and set the pointer to the value....

this might be the best way to do it...or at least the easiest to implement...
 
By combining MaheshRathi & Jyrixx ideas I have given a sample program. It may fulfill your requirement.

#include <iostream>
#include <cstring>

using namespace std;

typedef union
{
int iData;
double dData;
char sData[100];
}DATA;


class stackUnion
{
private :
struct
{
unsigned char type;
DATA value;
} mVar[5];
int index;
public :
stackUnion();
void push(int);
void push(double);
void push(char *);
DATA * pop();
};

stackUnion :: stackUnion()
{
index = 0;
cout << &quot;stackUnion Constructor&quot; << endl;
}

void stackUnion :: push(int iArg)
{
if(index >= 4)
{
cout << &quot;Error push : stack full :&quot; << endl;
return;
}
mVar[index].type = 0;
mVar[index++].value.iData = iArg;
}

void stackUnion :: push(double dArg)
{
if(index >= 4)
{
cout << &quot;Error push : stack full&quot; << endl;
return;
}
mVar[index].type = 1;
mVar[index++].value.dData = dArg;
};

void stackUnion :: push(char *sArg)
{
if(index >= 4)

{
cout << &quot;Error push : stack full&quot; << endl;
return;
}
mVar[index].type = 2;
strcpy(mVar[index++].value.sData, sArg);
}

DATA * stackUnion :: pop()
{
index--;
if(index < 0)
{
cout << &quot;Error push : Empty statck&quot; << endl;
return 0;
}
return & mVar[index].value;
}

int main()
{
stackUnion Stack;
Stack.push(10);
Stack.push(7.3);
Stack.push(&quot;Testing&quot;);
Stack.push(&quot;Maniraja S&quot;);
Stack.push(&quot;smara&quot;);
Stack.push(&quot;Exit&quot;);

cout << &quot;String data : &quot; << ( (char*) Stack.pop()) << endl;
cout << &quot;String data : &quot; << ( (char*) Stack.pop()) << endl;
cout << &quot;Double data : &quot; << *( (double *) Stack.pop()) << endl;
cout << &quot;int data : &quot; << *( (int *) Stack.pop()) << endl;
cout << &quot;Null data : &quot; << Stack.pop() << endl;
return 0;
}

If you want to have information about the stored data int Stack object then you have to return the struct variable from pop() instead of union variable (given that you have to declare the struct out side the class).

--Maniraja S
 
If your pushing on to the stack the numers as strings, do you have to return them as strings? If I push &quot;five&quot; do I have to return &quot;five&quot;? or do I return 5.0? Seems you could write a push that parses the data into floats.... and add them to the stack. The parse wouldn't e hard to write, but it would e time consuming. functions like the to lower and su string woud be very helpful... you may be able to find open free source for a program that does the converssion and just it's classes to your program.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top