Page 1 of 1

Stacks and Templates

Posted: Fri May 13, 2005 8:42 am
by Falco Girgis
Finally, we learn the stuff that I've really longed for. I had tried to learn templates on my own awhile back, but I couldn't understand from the book.

We've touched on templates and data structures enough that I can understand and learn more on my own now. Here's a sample program using a stack template:

Code: Select all

#include <iostream>
#include <string.h>
#include <stdio.h>
#include "stack.h"

using namespace std;

class Student {
	private:
		char name[50];
		float avg;
		int annoyance;
	public:
		void set_all(char n[], float a, int an) { 
			strcpy(name, n);
			avg = a;
			annoyance = an; 
		}
		char *get_name() { return name; }
		void set_name(char n[]) { strcpy(name, n); }
		float get_avg() { return avg; }
		void set_avg(float a) { avg = a; }
		int get_annoyance() { return annoyance; }
		void set_annoyance(int a) { annoyance = a; }
};

stack <Student> s_stack;
stack <Student> t_stack;

int Menu();
void AddStudent();
void DeleteStudent();
void ListStudents();

int main() {
	bool valid_menu = false;
	
	while(1) {
		switch(Menu()) {
			case 1:
				AddStudent();
				valid_menu = true;
				break;
			case 2:
				DeleteStudent();
				valid_menu = true;
				break;
			case 3:
				ListStudents();
				valid_menu = true;
				break;
			case 4:
				return 0;
				valid_menu = true;
				break;
			default:
				printf("That's not a valid menu option.\n");
		}
	}
	system("PAUSE");
	return 0;
}

int Menu() {
	int choice;
	printf("1) Add a Student\n");
	printf("2) Delete a Student\n");
	printf("3) List All Students\n");
	printf("4) Exit Program\n");
	cin >> choice;
	
	switch(choice) {
		case 1:
			return 1;
		case 2: 
			return 2;
		case 3: 
			return 3;
		case 4:
			return 4;
		default:
			return 0;
	}
}

void AddStudent() { 
	float avg;
	int annoyance;
	char name[50];
	bool a_valid = false, an_valid = false;
	
	printf("What is the name of the student?\n");
	getchar();
	gets(name);
	while(!a_valid) {
		printf("What is the student's average?\n");
		cin >> avg;
		if(avg >=0 && avg <= 100) a_valid = true;
	}
	while(!an_valid) {
		printf("What is the student's annoyance level?\n");
		cin >> annoyance;
		if(annoyance >= 0 && annoyance <= 4) an_valid = true;	
	}
	
	Student student;
	student.set_all(name, avg, annoyance);
	s_stack.push(student);
}

void DeleteStudent() {
	char name[50];
	Student current;
	
	printf("Please enter the name of the student that you wish to remove.\n");
	getchar();
	gets(name);
	
	current = s_stack.pop();
	t_stack.push(current);
	
	while(strcmp(current.get_name(), name) != 0 && s_stack.size() != 0) {
		current = s_stack.pop();
		t_stack.push(current);
	}
	
	if(strcmp(current.get_name(), name) == 0) {
		printf("Student found and destroyed.\n");
		t_stack.pop();
	}
	else {
		printf("Student not found\n");
	}
	
	while(t_stack.size() != 0) {
			s_stack.push(t_stack.pop());
	}
}

void ListStudents() {
	Student current;
	
	while(s_stack.size() != 0) {
		current = s_stack.pop();
		printf("Student Name - %s\nAverage - %f\nAnnoyance Factor - %d\n", current.get_name(), current.get_avg(), current.get_annoyance());
		t_stack.push(current);
	}
	
	while(t_stack.size() != 0) {
		s_stack.push(t_stack.pop());
	}
}

Posted: Tue May 17, 2005 11:51 am
by MarauderIIC
Using vectors (and good form; since vectors move the memory locations of its contents whenever the vector is modified, I employ new and delete in order to be able to retain pointers so that other things may refer to objects in my vector.)

Code: Select all

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector> //<---add

using namespace std;
/* ... */

vector<Student*>s_stack; //Vector of pointers
//<----> remove t_stack

int Menu();
void AddStudent();
void DeleteStudent();
void ListStudents();
void dealloc(); //<---add

int main() {
/* ... */
    dealloc(); //<---add
    return 0;
}

int Menu() {
/* ... */
}

void AddStudent() {
/* ... */
    Student* student = NULL;
    if (!(student = new Student)) {
        cerr << "Not enough memory for new student." << endl;
        //handle error
    }
    student->set_all(name, avg, annoyance);
    s_stack.push(student);
    //the vector now contains a pointer to this new obj.
    //dynamically allocated objects aren't removed until you delete them.
}

//This function now faster; don't have to delete and re-write.
void DeleteStudent() {
   char name[50];
   Student* current; //<--------
    vector<Student*>::iterator i; //<---add
   
   printf("Please enter the name of the student that you wish to remove.\n");
   getchar();
   gets(name);

    //<---->remove two lines relating to 'current'.
    //replace while loop and if(strcmp()) check w/ the following for loop
    for (i = s_stack.begin();i != s_stack.end();++i) {
        current = *i;
        if (strcmp(current->get_name(), name) == 0) {
            delete current;
            current = NULL;
            s_stack.erase(i);
            printf("Student found and destroyed\n");
            //that's all we needed; get out.
            return;
        }
    }

    printf("Student not found\n");

    //<--->remove while loop, no longer have temp stack
}

//This function is now faster, don't have to delete and re-write.
void ListStudents() {
   Student* current;    //<---modify
    vector<Student*>::iterator i;
    //replace while loop
    for(i = s_stack.begin();i != s_stack.end();++i) {
        current = *i;
        printf("Student Name - %s\nAverage - %f\nAnnoyance Factor -            %d\n",
            current->get_name(), current->get_avg(), 
            current->get_annoyance()); //<--- "." becomes "->"
        //<--->remove t_stack.push()
    }

    //<---->remove re-push while loop.
} 

void dealloc() {
    vector<Student*>::iterator rmvme;
    //rmvme is a pointer to an item in s_stack
    //since items in s_stack are pointers, it's a pointer to a pointer.
    //in all cases, dereferencing a vector iterator gives you the item
    //of the type in brackets, in this case, Student*.
    //in this case, rmvme is of type Student**.
    for (rmvme = s_stack.begin();rmvme != s_stack.end();++rmvme) {
        delete *rmvme;
        //deletes what Student* points to, which is correct.
        *rmvme = NULL;
    }
    s_stack.clear();
}
*Edit: forgot /code :)