It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
#include <iostream>
#include <cstring>
#include <vector>
#include "list.cpp"
#include <cmath>
using namespace std;
struct HashEntry{
int key;
List<string> list;
HashEntry(int k)
{
key=k;
}
};
class Hash{
private:
HashEntry *Table[100];
int a;
public:
Hash(int A);
void insert(string word);
void Lookup(string word);
};
Hash::Hash(int A)
{
a=A;
}
void Hash::insert(string word)
{
int c=0;
for (int i=0;i<word.size();i++)
{
int b=(int)((a^i)*(word[i]));
c+=b;
}
c%=100;
List<string> list;
if (Table[c-1]==NULL) //if the respective bucket doesnot have any string
Table[c-1]=new HashEntry(c-1);
Table[c-1]->list.insertAtTail(word);
}
void Hash::Lookup(string word)
{
int c=0;
for (int i=0;i<word.size();i++)
{
int b=(int)((a^i)*(word[i]));
c+=b;
}
cout<<"one"<<endl;
c%=100;
Table[c-1]->list.searchFor(word);
cout<<"two"<<endl;
}
I am making a hash table using seperate chaining taking.my hash function is making a polynomial equation using a constant 'a' whose power is increasing with the index of the letter in a word.(a^0xb+a^1xb+a^2xb+...) , where b is a letter in the word which is being hashed and then I take mod(100) of the final answer.The problem i am facing is in lookup function.when I test the lookup function,the searchFor() function which is in part of part Linked list class does not work although it works fine on its own and i get an segmentation fault after the cout<<"one" which i used to debug .I am sorry for bothering but I just can't understand the problem here.The linked list class file is below.I am just pasting the function in which i am having problem
#ifndef __LIST_H
#define __LIST_H
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
/* This class just holds a single data item. */
template <class T>
struct ListItem
{
vector<string> words;
T value;
ListItem<T> *next;
ListItem<T> *prev;
ListItem(T theVal)
{
this->value = theVal;
this->next = NULL;
this->prev = NULL;
}
};
/* This is the generic List class */
template <class T>
class List
{
ListItem<T> *head;
public:
// Constructor
List();
// Copy Constructor
List(const List<T>& otherList);
// Destructor
~List();
// Insertion Functions
void insertAtHead(T item);
void insertAtTail(T item);
void insertAfter(T toInsert, T afterWhat);
void insertSorted(T item);
void printList();
// Lookup Functions
ListItem<T> *getHead();
ListItem<T> *getTail();
void *searchFor(T item);
// Deletion Functions
void deleteElement(T item);
void deleteHead();
void deleteTail();
// Utility Functions
int length();
};
#endif
template <class T>
void List<T>::searchFor(T item)
{
ListItem<T> *temp=head;
if (temp!=NULL)
{
while (temp->next!=NULL)
{
T sample=temp->value;
if (sample==item)
{
cout<<"String found";
return;
}
temp=temp->next;
}
T s=temp->value;
if (s==item)
{
cout<<"String found";
return;
}
}
}
In addition to my comment above, which led you to find one of the bugs you have, I will add this:
The reason why you crash is that your Hash class mismanages the hash table. First of all, you allocate an array of 100 HashEntry pointers:
HashEntry *Table[100];
Notice that you never set those pointers to anything - so they're pointing to who knows what. Perhaps they will, by sheer luck, point to NULL, but the chances of that are miniscule - you're way way way more likely to win the lottery. So, you are accessing some random memory - and that's bad.
The solution to that is to set each entry to NULL explicitly using a loop in your constructor. You will also need a destructor to free any allocated entries, so that you can delete it and not leak memory, because leaking is bad.
But an interesting question is why do it like that at all? Why not simply declare the buckets like this:
HashEntry Table[100];
That way all your buckets are allocated as part of the Hash object and you don't have to worry about dynamically allocating and deallocating buckets, checking pointers for NULL etc.
One problem with doing that is that your HashEntry constructor requires an int argument. It's unclear why that argument is necessary; I don't think that you need it and and you could just remove it.
This one change would have simplified your code dramatically and eliminated three bugs and the crash.
Related
I would like to know how to update/modify the following class definition to implement a queue. What class elements or methods would change?
Im preparing for my final exam and this is one of the questions asked on a previous exam that I answered incorrectly. My professor is adamant on using this specific class structure to implement a queue, however we did not go over it in class and it's not in our textbook either.
#include <iostream>
#include <string>
using namespace std;
class StringNode{
private:
string elem;
stringNode* next;
friend class StringLinkedList;
};
//Code fragment 1
class StringLinkedList{
public:
StringLinkedList(){
head == NULL;
}
~StringLinkedList();{
while(!empty()){
removeFront();
}
}
bool empty() const{
return head == NULL;
}
const string& front() const{
return head->elem;
}
void addFront(const string& e);
void removeFront();
private:
StringNode* head;
};
//Code fragment 2
Accessing the tail of a singly linked list is an O(n) operation. Unless the implementation is properly encapsulated, and the internal structure of the list cannot directly be manipulated, in which case it would be possible for that implementation to safely keep track of the tail node of the list, allowing operations on the tail to be O(1).
So I am trying to implement a Stack using a linked list and classes. Right now I have 6 different files: node.h, node.cpp, LL.h, LL.cpp, Stack.h, and Stack.cpp. I want to complete the Stack.h and Stack.cpp files so that they work as they should. I already implemented the linked list functions and they work as they should. Here is the code:
node.h :
// node.h
class node { // node class used in the LL (linked list) class
private:
node * next; // Pointer to next node of an LL
int data; // integer data stored in this node
public:
node(int x, node * n); // Constructor
~node(); // Destructor
void set_data(int x); // Change the data of this node
void set_next(node * n);// Change the next pointer of this node
int get_data(); // Access the data of this node
node * get_next(); // Access the next pointer of this node
};
LL.h :
// LL.h
#include "node.h"
// Linked list class, used in the Stack class
class LL {
private:
node * head; // pointer to first node
node * tail; // pointer to last node
public:
LL(); // Constructor
~LL(); // Destructor
void prepend(int value); // add a node to the beginning of the LL
int removeHead(); // remove the first node of the LL
void print(); // print the elements of the LL
node * get_head(); // access the pointer to the first node of the LL
};
Stack.h:
// Stack.h
#include "LL.h"
class Stack {
private:
LL_t intlist;
public:
Stack(); // Constructor
~Stack(); // Destructor
void push(int value);
int pop();
int isEmpty();
void print();
};
And lastly,
Stack.cpp:
// Stack.cpp
#include "Stack.h"
#include <stdio.h>
Stack::Stack() {
head= NULL;
tail= NULL;
}
Stack::~Stack() {
delete intlist;
}
int Stack::isEmpty() {
return (head==NULL);
}
void Stack::push(int value) {
head= value;
}
int Stack::pop() {
if ( !isEmpty() ) {
int temp= tail->get_data();
delete tail;
return temp;
}
return -1;
}
I am having compiling issues. It says get_data() is undefined and "head" and "tail" is undefined, even though I have " #include "LL.h" " in Stack.h and in LL.h, I have "#include "node.h" ", so they all build on one another so it should work correct? I want it to compile so I can see if I am implementing Stack.h and Stack.cpp correctly. Do you see any issues with the way I am implementing them? If so, can you point them out? Also, any idea as to why I am getting these compiling issues? Any help appreciated!
Let's look at your actual questions
Stack::Stack() {
head= NULL;
tail= NULL;
}
results in error "head" and "tail" is undefined. Now look at the header files, where are the declarations of head and tail? Answer, in the LL class not the Stack class. It's the responsibility of the LL class to initialise head and tail which it does the in the LL class default constructor. So your Stack constructor should look like this
Stack::Stack() {
}
Whenever you have a constructor for a class which contains another class a constructor for the other class will be called. In the case of Stack the default constuctor for LL is called implicitly, and this initialises head and tail for you. You don't have to do anything.
Now lets look at some more of your implementation.
Stack::~Stack() {
delete intlist;
}
intList is not a pointer, so it cannot be deleted. It's clear that you are trying to 'call` the destructor for your list, but just like the constructor this happens automatically. Your destructor should look like this
Stack::~Stack() {
}
Or you could (probably should) just remove it completely.
Moving on
int Stack::isEmpty() {
return (head==NULL);
}
Again you are trying to access head somewhere it isn't accessible. Your Stack class has an LL intlist object and that's what it should use, so (for instance)
int Stack::isEmpty() {
return intlist.get_head() == NULL;
}
Smae thing here
void Stack::push(int value) {
head= value;
}
should be
void Stack::push(int value) {
intlist.prepend(value);
}
Use the object that the stack has (the intlist) not the internals of other objects.
I'll leave you do sort out the rest. But you must understand the division of responsbilities that exist in your class design. The Stack class should not (and cannot) concern itself with the internals of the LL class. All that the operations that Stack needs to perform should be doable with the public interface of the LL class. If not then it's the LL class that needs to change.
Also note that your pop implementation is not just wrong in executuion it's wrong in concept. Pop should remove the head of the list, not the tail. A stack is a LIFO list (last in, first out) so pop removes the most recentaly added item. Now looking at the LL class there is a removeHead method (hint, hint).
I have been solving a question, Dijkstra's Algorithm, in C++. I've implemented it using adjacency list.
So I have a class for a node, a class for a minHeap, and a class for the Graph.
class node
{
int vertex,weight;
node *next;
friend class Graph;
friend class minHeap;
public:
node();
node(int,int);
};
node::node(){
vertex=weight=0;
next=0;
}
node::node(int v,int wt){
vertex=v;
weight=wt;
next=0;
}
Do I define the minHeap class this way (without a friend function) and create an object in the getDijkSP() function normally, which allows me to use the object only in that function?
class minHeap
{
node *heap;
int heapSize,capacity,*pos;
public:
minHeap(int);
void addElement(node);
node extractMin();
void minHeapify(int);
void decreaseKey(int,int);
};
minHeap::minHeap(int cap){
heap=new node[capacity=cap];
heapSize=-1;
pos=new int[cap]();
} //eliminating other methods
class Graph
{
node **adjList;
int v;
bool *visited;
public:
Graph(int);
void addEdge(int,int,int);
void removeEdge(int,int);
bool existsEdge(int,int);
void getDijkSP();
};
Graph::Graph(int vertices){
adjList=new node*[v=vertices];
for(int i=0;i<v;i++)
adjList[i]=NULL;
}
void Graph::getDijkSP(){
minHeap hp(v); //here
hp.addElement(node(0,0));
for(int i=1;i<v;i++)
hp.addElement(node(i,INT_MAX));
while(!hp.isempty()){
node temp=hp.extractMin();
cout<<temp.vertex<<" "<<temp.weight<<endl;
for(node *current=adjList[temp.vertex];current;current=current->next)
hp.decreaseKey(current->vertex,current->weight+temp.weight);
}
}
(OR) Do I define the minHeap class with a friend function, so that I can create an object of the minHeap class using the new keyword? (And this helps me define the minHeap object in the scope of the Graph class, so that I can use it in all of its functions for other capabilities as well.)
class minHeap
{
node *heap;
int heapSize,capacity,*pos;
friend class Graph; //say like this
public:
minHeap(int);
void addElement(node);
node extractMin();
void minHeapify(int);
void decreaseKey(int,int);
};
minHeap::minHeap(int cap){
heap=new node[capacity=cap]();
heapSize=-1;
pos=new int[cap]();
}
class Graph
{
node **adjList;
int v;
bool *visited;
minHeap *hp; //and do this
public:
Graph(int);
void addEdge(int,int,int);
void removeEdge(int,int);
bool existsEdge(int,int);
void getDijkSP();
};
Graph::Graph(int vertices){
adjList=new node*[v=vertices];
for(int i=0;i<v;i++)
adjList[i]=NULL;
hp=new minHeap(v); //dynamic allocation
}
void Graph::getDijkSP(){
hp->addElement(node(0,0));
for(int i=1;i<v;i++)
hp->addElement(node(i,INT_MAX));
while(!hp->isempty()){
node temp=hp->extractMin();
cout<<temp.vertex<<" "<<temp.weight<<endl;
for(node *current=adjList[temp.vertex];current;current=current->next)
hp->decreaseKey(current->vertex,current->weight+temp.weight);
}
}
I have read this and a few other articles, but specifically want to know the advantages, disadvantages and the appropriateness of both the methods for such similar kinds of questions.
I've provided the constructors for the classes for better clarity.
Short answer would be NO. I would suggest you to read up on smart pointers and rewrite this whole mess. In C++ there is no real reason to use manual allocation in so simple project as this ever.
Also instead of assigning 0 or NULL to a pointer use nullptr, which is C++ symbol only for null pointers unlike the previous mentioned C values that are actually just a int 0 which may cause some unintentional errors.
Edit in response to your comment:
So I've decided to rewrite your code using actual modern C++ instead of this C code with simple classes. In your whole example there are almost no pointers or dynamic allocations needed. I wasn't absolutely sure who exactly should own the actual nodes so from the example I assumed that the MinHeap should. Also I didn't get the point of MinHeap::pos and Graph::visited from what I could see. I can explain any part of that code in more detail, just ask which.
Here is the code:
class Node {
// Only friend class required if you insist on keeping members of Node private.
// If they aren't meant to change, consider declaring them as public and const.
template <unsigned Size> friend class Graph;
public:
Node(int v, int wt) : vertex(v), weight(wt) {}
private:
// Default values written in here right after declarations
// There is no need for a default constructor. You never call it anyway.
int vertex;
int weight;
Node* next = nullptr;
};
// Template parameter because of internal use of std::array.
// If the capacity shouldn't be constant, use std::vector and remove template.
template <unsigned Capacity>
class MinHeap {
public:
// No constructor needed
// ---------------------
// One small tip: write parameter names in function declarations
// even if they aren't needed there for better readability of your code.
void addElement(Node n) { /* impl */ }
Node extractMin() { /* impl */ }
unsigned capacity() { return Capacity; }
bool isEmpty() { return heap.isEmpty(); }
private:
// Default values written in here right after declarations
int heapSize = -1;
std::array<Node, Capacity> heap;
};
// Template parameter because of internal use of std::array.
// If the vertex count shouldn't be constant, use std::vector and remove template.
template <unsigned Vertices>
class Graph {
public:
// No constructor needed
// ---------------------
void getDjikSP() {
hp.addElement({0, 0});
for (unsigned i = 1; i < hp.capacity(); ++i)
hp.addElement({0, INT_MAX});
while (!hp.isEmpty()) {
Node tmp = hp.extractMin();
std::cout << tmp.vertex << " " << tmp.weight << std::endl;
for (Node* current = adjList[tmp.vertex]; current != nullptr; current = current->next)
hp.decreaseKey(current->vertex, current->weight + tmp.weight);
}
}
private:
// Default values written in here right after declarations
std::array<Node*, Vertices> adjList;
MinHeap<Vertices> hp;
};
There is still a lot of space for improvements of this code, for example the MinHeaP::extractMin should maybe return Node&& if it is removed from the heap or const Node& if it should return a reference to the top, etc. To address all the problems and inefficiencies this can still have I would need to see the full code with all functions.
I have an assignment where I have to create a linked list and add and remove items from it. I'm having a problem understanding how to initialize the linked list in my constructor and adding items to it as well.
Here's my header file for it.
#ifndef CONGERA3_H
#define CONGERA3_H
const int MAX_STRING = 6;
typedef char Element300[MAX_STRING + 1];
class Queue300
{
public:
Queue300 ();
Queue300 (Queue300 &old);
~Queue300();
void enQueue300 (const Element300);
void deQueue300 (Element300);
void view300();
private:
struct Node300;
typedef Node300 * NodePtr300;
struct Node300
{
Element300 element;
NodePtr300 next;
};
NodePtr300 front, rear;
};
#endif
Here's my implementation file as well. I've removed the other functions for now, I feel like if I can get the constructor and enQueue down I can figure out the rest of them.
#include <iostream>
#include "congera3.h"
using namespace std;
Queue300::Queue300 ()
{
front = NULL;
return;
}
void Queue300::enQueue300 (const Element300 element)
{
Node300 temp;
temp.element = element;
}
I feel like I need to add a lot more to the constructor, such as setting the rear to point to the front. In the enQueue I think I need to have rear point towards the element I'm passing in and then have that element's next point towards front.
I have some experience with Java and Eclipse, but I'm new to C++, and trying to teach myself. I apologize if this is a simple question, or one that has already been asked (though I looked around for a while.) I'm on a Windows 8.
I'm trying to make a sorted linked list (which is relatively unimportant.) I get:
Info: Nothing to build for Working.
Here's my code:
/*
* SortedList class
*/
#include <string>
#include <fstream>
#include<iostream>
#include "SortedList.h"
using namespace std;
//the ListNode Structure
struct ListNode {
string data;
ListNode *next;
};
//the head of the linked list and the pointer nodes
ListNode head;
ListNode *prev, *current;
// insert a string into the list in alphabetical order
//now adds a string to the list and counts the size of the list
int Insert(string s){
//make the new node
ListNode temp;
temp.data = s;
//the node to traverse the list
prev = &head;
current = head.next;
int c = 0;
//traverse the list, then insert the string
while(current != NULL){
prev = current;
current = current->next;
c++;
}
//insert temp into the list
temp.next = prev->next;
prev->next = &temp;
return c;
}
//Return the number of times a given string occurs in the list.
int Lookup(string s){
return 0;
}
//prints the elements of the list to ostream
void Print(ostream &output){
}
int main( int argc, char ** argv ) {
cout << Insert("a") << endl;
cout << Insert("b") << endl;
cout << Insert("d") << endl;
}
And here's my header:
using namespace std;
#ifndef SORTEDLIST_H_
#define SORTEDLIST_H_
class SortedList {
public:
// constructor
SortedList();
// modifiers
int Insert(string s);
// other operations
int Lookup(string s) const;
void Print(ostream &output) const;
private:
struct ListNode {
string data;
ListNode *next;
};
// pointer to the first node of the list
ListNode head;
ListNode *prev, *current;
};
#endif /* SORTEDLIST_H_ */
Any help would be greatly appreciated.
Why don't you use std::deque (in header deque)? It probably has all the functionality you are seeking, it is fully tested and optimised. If you need a deque with a bit more of functionality, create a class that inherit from it and add the functions you need. Have a look to http://en.cppreference.com/w/cpp/containe and pick up the container that best suits your needs.
As a general advise, if something you need is already available in some good and stable library (STL, boost, GSL, Armadillo or similar), much better use it rather than to write+debug+optimise it yourself from scratch. As a general advise, focus your efforts on the code that is unique to your application, and reuse what has already be done (BUT only if it has been well tested, do not use crappy half cooked libraries).