#include <iostream>
#include <list>
using namespace std;
const int TABLESIZE = 3;
class HashTable
{
public:
string k;
int v;
HashTable* next;
HashTable(string k, int v)
{
this->k = k;
this->v = v;
next = NULL;
}
};
class HashMapTable
{
private:
HashTable **t;
public:
HashMapTable()
{
t = new HashTable * [TABLESIZE];
for (int i = 0; i < TABLESIZE; i++)
{
t[i] = NULL;
}
}
int HashFunction(int v)
{
return v % TABLESIZE;
}
void Insert(string k, int v)
{
int hV = HashFunction(v);
HashTable* p = NULL;
HashTable* en = t[hV];
while (en!= NULL)
{
p = en;
en = en->next;
}
if (en == NULL)
{
en = new HashTable(k, v);
if (p == NULL)
{
t[hV] = en;
} else
{
p->next = en;
}
} else
{
en->v = v;
}
}
void PrintTable()
{
for (int i = 0; i < TABLESIZE; i++)
{
if(t[i] != NULL)
{
cout << t[i]->k << " " << t[i]->v << endl;
}
}
}
~HashMapTable()
{
for (int i = 0; i < TABLESIZE; i++)
{
if (t[i] != NULL)
delete t[i];
delete[] t;
}
}
};
int main()
{
HashMapTable HT;
cout << "entering the pairs now" << endl;
HT.Insert("Boramir", 25);
HT.Insert("Legolas", 101);
HT.Insert("Gandalf", 49);
cout << "printing the pairs now" << endl;
HT.PrintTable();
}
My issue is that not all the key value pairs in the table are being printed depending on the table size. If it's 3 (the desired amount) only 2 print, but if it's at least 7, they all print? I'm not sure what piece of my code is causing this to happen. Also, if there are multiple pairs in one bucket, the second/third/etc pair doesn't print and I'm not sure why. Thanks for any help.
Related
Everything works fine apart from the array that's supposed to remember the connected nodes for each node, although it counts only some of them and I'm not sure why. I believe the problem is here:
if (G->v[j] != NULL || G->v[i] != NULL)
However, I'm not sure how to change it.
#include <iostream>
#include <time.h>
#include <list>
#include <iterator>
#include <stack>
#include <queue>
#include "Profiler.h"
using namespace std;
# define MAX_SIZE 20
class Node
{
public:
int key;
int colour; // -1 not visited(white), 0 under visit(gray), 1 visited(black)
Node* p;
int d, f;
list<Node*> adj;
};
Node* newNode(int key) //constructor
{
Node* node = new Node();
node->key = key;
node->colour = -1; // white, not visited
node->d = 0;
node->f = 0;
node->p = NULL;
return node;
}
class Edge
{
public:
Node *v1,*v2;
};
Edge* newEdge(Node* u, Node* v)
{
Edge* edge = new Edge();
edge->v1 = u;
edge->v2 = v;
return edge;
}
class Graph
{
public:
Node* v[MAX_SIZE];
list<Edge*> e;
};
Graph* newGraph(int nb_of_vertices, int nb_of_edges)
{
Graph* G = new Graph();
int i, j;
for (i = 0; i < nb_of_vertices; i++)
{
G->v[i] = NULL;
}
for (i = 0; i < nb_of_vertices; i++)
{
Node* v1 = newNode(i);
G->v[i] = v1;
do
j = rand() % (nb_of_vertices-1);
while (j == i);
if (G->v[j] != NULL || G->v[i] != NULL)
{
Node* v2 = newNode(j);
G->v[j] = v2;
G->v[i]->adj.push_back(v2);
Edge* edge = newEdge(v1, v2);
G->e.push_back(edge);
}
}
return G;
}
void printGraph(Graph* G, int n)
{
list <Node*> ::iterator it;
for (int i = 0; i < n; i++)
{
cout << G->v[i]->key << '\t' << G->v[i]->colour << '\t' << G->v[i]->d << '\t' << G->v[i]->f << '\t';// << G->v[i]->p << '\t';
for (it = G->v[i]->adj.begin(); it != G->v[i]->adj.end(); ++it)
{
cout << (*it)->key << ' ';
}
cout << '\n';
}
list <Edge*> ::iterator it2;
for (it2 = G->e.begin(); it2 != G->e.end(); ++it2)
{
cout << (*it2)->v1->key << "-" << (*it2)->v2->key << ' ';
}
cout << '\n';
}
queue <Node*> solution;
stack <Node*> topsort;
int no_cycle = 1;
void DFSvisit(Graph* G, Node* v, int& time)
{
Node* node = newNode(0);
time++;
v->d = time;
v->colour = 0;
while (!v->adj.empty())
{
node = v->adj.front();
v->adj.pop_front();
if (v->colour == 0)
no_cycle = 0;
if (node->colour == -1)
{
node->p = v;
DFSvisit(G, node, time);
}
}
v->colour = 1;
time++;
v->f = time;
solution.push(v);
topsort.push(v);
}
void DFS(Graph* G, int n)
{
int time = 0, i;
for (i = 0; i < n; i++)
{
if (G->v[i]->colour == -1)
DFSvisit(G, G->v[i], time);
}
}
int main()
{
srand(time(NULL));
int nb_of_vertices = 10, nb_of_edges = 3;
Graph* G = newGraph(nb_of_vertices, nb_of_edges);
printGraph(G, nb_of_vertices);
DFS(G, nb_of_vertices);
printGraph(G, nb_of_vertices);
// DFS traversal
cout << "\nDFS TRAVERSAL\n";
while (!solution.empty())
{
cout << solution.front()->key << " ";
solution.pop();
}
cout << '\n';
// Tarjan's algorithm
// Topological sort
if (no_cycle)
{
cout << "\nTOPOLOGICAL SORTING\n";
while (!topsort.empty())
{
cout << topsort.top()->key << " ";
topsort.pop();
}
}
else
cout << "\nImpossible to perform topological sort, the generated graph contains cycles.\n";
return 0;
}
for the bigraph maximum matching algorithm, I used 2 hash table(unordered_map)to solve it, but when I compiling my code, IDE told me C2100, I even don't know where my code is false, it just happened in the "xhash" document, and I think this problem is associated with iterator. Anyway, please help me to figure out this question, Thanks !
#include<iostream>
#include<queue>
#include<unordered_map>
#include<vector>
using namespace std;
struct Edge
{
int to;
int go;
int length;
Edge* next;
int ID;
};
struct Dot
{
int data;
Edge* first;
};
class Web
{
public:
Web(int num);
~Web();
void Insert(int i, int j, int w);
void DFS(int s, int* visited,queue<int>&);
void BFS(int s, int* visited);
void show()
{
for (int i = 0; i<n; i++)
{
Edge* p = D[i].first;
if (p != NULL)
{
cout << p->length << " ";
p = p->next;
}
}
}
void MostMatch();
private:
int e;
int n;
Dot* D;
vector<Edge*> E;
};
Web::Web(int num)
{
e = 0;
n = num;
D = new Dot[num];
for (int i = 0; i<num; i++)
{
D[i].first = NULL;
D[i].data = 0;
}
}
Web::~Web()
{
delete[] D;
}
void Web::Insert(int i, int j, int w)
{
Edge* p = D[i].first;
int count = 0;
if (D[i].first == NULL)
{
D[i].first = new Edge;
D[i].first->next = NULL;
D[i].first->length = w;
D[i].first->to = j;
D[i].first->go = i;
D[i].first->ID = count++;
E.push_back(D[i].first);
}
else
{
while (p->next != NULL)
p = p->next;
Edge* q = new Edge;
p->next = q;
q->next = NULL;
q->length = w;
q->go = i;
q->to = j;
q->ID = count++;
E.push_back(q);
}
p = D[j].first;
if (D[j].first == NULL)
{
D[j].first = new Edge;
D[j].first->next = NULL;
D[j].first->length = w;
D[j].first->to = i;
D[j].first->ID = count;
e++;
}
else
{
while (p->next != NULL)
p = p->next;
Edge* q = new Edge;
p->next = q;
q->next = NULL;
q->length = w;
q->to = i;
q->ID = count;
e++;
}
}
void Web::MostMatch()
{
cout << "make sure it is a biggraph, press Q to quit." << endl;
char ch;
cin >> ch;
if (ch == 'Q')
{}
else
{
unordered_map<int, int> mape;
unordered_map<int, int> mapd;
int count = 0;
for (int i = 0; i < n; i++)
{
Edge* p;
if (D[i].first)
{
p = D[i].first;
if (mapd.find(i) == mapd.end())
{
while (p)
{
if (mapd.find(p->to) == mapd.end())
{
mapd.insert(i,count++);
mapd.insert(p->to, count++);
mape.insert(p->ID, i);
break;
}
}
}
}
}
unordered_map<int, int>::iterator iter = mape.begin();
while (iter != mape.end())
{
Edge* p = D[E[iter->first]->go].first, *q = D[E[iter->first]->to].first;
while (p)
{
if (mapd.find(p->to) == mapd.end())
{
while (q)
{
if (mapd.find(q->to) == mapd.end())
{
mapd.insert(p->to, count++);
mapd.insert(q->to, count++);
mape.insert(p->ID, count++);
mape.insert(q->ID, count++);
mape.erase(iter->first);
break;
}
}
break;
}
}
iter++;
}
for (iter = mape.begin(); iter != mape.end(); iter++)
{
cout << "v" << E[iter->first]->go << " to v" << E[iter->first]->to << " ID: " << E[iter->first]->ID << endl;
}
}
}
int main()
{
Web w1(8);
w1.Insert(0, 3, 1);
w1.Insert(1, 4, 1);
w1.Insert(1, 5, 1);
w1.Insert(2, 5, 1);
w1.Insert(2, 6, 1);
w1.Insert(2, 7, 1);
w1.Insert(3, 7, 1);
w1.MostMatch();
return 0;
}
I even don't know where my code is false
This is a good reason to minimize your code: https://stackoverflow.com/help/mcve
If your compiler doesn't tell you the error message/line (and, I think, it actually does), try a different one, there is a high chance they are compatible. This one: https://www.onlinegdb.com/online_c++_compiler tells me that lines
mapd.insert(i,count++);
and similar are wrong. Replacing them in the following way compiles:
mapd[i] = count++;
I made a program that involves a binary search tree. Basically, my segregates a set of input integers into "bins" in such a way that each bin are equal in value when their contents are summed.
#include <iostream>
#include <vector>
#ifndef DEBUG
#define DEBUG 0
#endif
using namespace std;
class Node {
private:
int weight = 0;
Node* leftNode;
Node* rightNode;
int bin = 0;
public:
Node() {}
Node(int weight) {
this->weight = weight;
}
void printContents() {
cout << weight << " ";
if(leftNode) leftNode->printContents();
if(rightNode) rightNode->printContents();
}
void addNode(Node* node) {
if(node->getWeight() <= this->weight) {
if(leftNode) leftNode->addNode(node);
else leftNode = node;
} else {
if(rightNode) rightNode->addNode(node);
else rightNode = node;
}
}
Node* getNode(int weight) {
if(!hasChildren()) {
if(this->weight == weight && bin == 0) return this;
else return nullptr;
} else {
Node* n = nullptr;
if(this->weight == weight && bin == 0) {
n = this;
}
Node* child;
if(leftNode && weight <= this->weight) {
child = leftNode->getNode(weight);
} else if(rightNode && weight > this->weight) {
child = rightNode->getNode(weight);
} else {
child = nullptr;
}
if(child) {
return child;
}
else return n;
}
}
bool hasChildren() {
if(leftNode || rightNode) return true;
else return false;
}
int getWeight() {
return weight;
}
void setBin(int bin) {
this->bin = bin;
}
int getBin() {
return bin;
}
void unbin() {
bin = 0;
}
void operator=(Node* node) {
this->weight = node->weight;
this->leftNode = node->leftNode;
this->rightNode = node->rightNode;
this->bin = node->bin;
}
};
class Bin {
private:
int binNum = 0;
int weight = 0;
int targetWeight = 0;
vector<Node*> nodes;
public:
Bin(int binNum, int targetWeight) {
this->binNum = binNum;
this->targetWeight = targetWeight;
}
void addNode(Node* node) {
weight += node->getWeight();
node->setBin(binNum);
nodes.push_back(node);
}
Node* removeLatestNode() {
Node* n = nodes.back();
weight -= n->getWeight();
nodes.pop_back();
n->unbin();
return n;
}
int getWeight() {
return weight;
}
bool isFull() {
if(weight == targetWeight) return true;
else return false;
}
bool willBeOverloaded(int x) {
if(weight + x > targetWeight) return true;
else return false;
}
};
void organize(Node* rootNode, int bins, int weightPerBin) {
#if DEBUG
cout << "Weight per bin: " << weightPerBin << endl;
#endif
for(int i = 1; i <= bins; i++) {
Bin bin(i, weightPerBin);
int x = weightPerBin;
while(!bin.isFull()) {
while(x > 0) {
Node* n = rootNode->getNode(x);
if (n) {
#if DEBUG
cout << "bin " << i << " : ";
cout << n->getWeight() << endl;
#endif
if (!bin.willBeOverloaded(n->getWeight())) {
#if DEBUG
cout << "adding to bin " << i << " : " << n->getWeight() << endl;
#endif
bin.addNode(n);
x = weightPerBin - bin.getWeight();
if(bin.isFull()) break;
} else {
x--;
}
} else {
x--;
}
}
if(!bin.isFull()) {
Node* n = bin.removeLatestNode();
#if DEBUG
cout << "removing from bin " << i << " : " << n->getWeight() << endl;
#endif
x = n->getWeight() - 1;
}
}
}
}
int getWeightPerBin(int* weights, int n, int bins) {
int weight = 0;
for(int i = 0; i < n; i++) {
weight += weights[i];
}
return weight/bins;
}
int main() {
int n;
int *weights;
int bins;
cin >> n;
weights = new int[n];
for(int i = 0; i < n; i++)
cin >> weights[i];
cin >> bins;
Node nodes[n];
nodes[0] = new Node(weights[0]); //the root node
for(int i = 1; i < n; i++) {
nodes[i] = new Node(weights[i]);
nodes[0].addNode(&nodes[i]);
}
organize(&nodes[0], bins, getWeightPerBin(weights, n, bins));
for(int i = 0; i < n; i++) {
cout << nodes[i].getBin() << " ";
}
return 0;
}
I developed this program in CLion IDE and it works perfectly. Recently I discovered that Xcode can also be used to develop C++ programs so I tried using it with the exact same code. But when I run the program, it always returns:
xcode error screenshot
It returns an error called EXC_BAD_ACCESS which is the first time I've encountered it. I'm a student who has a good background in Java and is currently learning C++ for a class. My knowledge in C++ is limited and I'd like to know whether this problem is due to Xcode or is inherent in my code.
You don't initialize leftNode and rightNode - they are not magically initialized to nullptr, so calling a function like
void printContents() {
cout << weight << " ";
if(leftNode) leftNode->printContents();
if(rightNode) rightNode->printContents();
}
will have Undefined Behaviour.
I suggest you initialize your variables before using them.
I am writing chained hash table code.
I do not understand why my linked list traversal does not stop at NULL when I set entry->next->next = NULL after I insert.
I have omitted code which is not useful for my question:
What is causing the linked list traversal in `printTable' to loop forever?
ChainHash.h:
class Entry {
private:
string key;
int value;
Entry *next;
friend class HashTable_CH;
public:
Entry(string k, int v) {
key = k;
value = v;
next = NULL;
}
};
class HashTable_CH {
private:
Entry **slots;
const int DEFAULT_CAP = 11;
const float load_factor = 0.5;
int capacity;
int size;
//int isPrime(int n) {
//int calculateGrowSize() {
int hash(string k) {
int c = 0;
for (int i = 0; i < k.length(); i++)
c += int(k[i]);
return c % capacity;
}
//int probe(int hash, int index) {
public:
HashTable_CH() {
slots = new Entry*[DEFAULT_CAP];
capacity = DEFAULT_CAP;
size = 0;
for (int i = 0; i < DEFAULT_CAP; i++)
slots[i] = NULL;
}
void Insert(string key, int value) {
if (float(size) / float(capacity) >= load_factor)
//grow();
return;
int h = hash(key);
if (slots[h] == NULL) {
slots[h] = new Entry(key, value);
size++;
return;
} else {
Entry *entry = slots[h];
while (entry->next != NULL)
entry = entry->next;
entry->next = new Entry(key, value);
entry->next->next = NULL;
}
}
//bool Search(string, int &value) {
//void Remove(string key) {
void printTable() {
for (int i = 0; i < capacity; i++) {
cout << "Slot " << i << ": ";
if (slots[i] == NULL)
cout << "*****";
else {
Entry **temp = slots;
while (temp != NULL) {
cout << "Key: " << slots[i]->key << ", " << slots[i]->value;
}
}
} cout << "\n";
} cout << "\n";
}
};
testChainedHash.cpp:
#include"ChainHash.h"
int main() {
HashTable_CH t1;
t1.Insert("froyo", 500);
t1.Insert("froyo", 600);
t1.Insert("froyo", 700);
t1.printTable();
}
Here:
while (temp != NULL) {
cout << "Key: " << slots[i]->key << ", " << slots[i]->value;
}
Do you see the problem?
I tried to implement BFS for graphs using link list but i have some issues with it, using a queue it only displays the nodes of that origin and not after it. The answer should be 2031 but i only get 203.
The code is below:
#include <iostream>
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <queue>
using namespace std;
class linkListNode
{
public:
linkListNode *next;
int destination;
bool visited;
linkListNode()
{
next = NULL;
destination =0;
visited=false;
}
};
class linkList
{
public:
linkListNode *head;
linkList()
{
head = NULL;
}
// append type insert
void insert(int value)
{
linkListNode *temp2 = new linkListNode;
temp2->destination = value;
temp2->next = NULL;
linkListNode *nodePtr = new linkListNode;
if (head == NULL)
{
head = temp2;
temp2->next = NULL;
}
else
{
nodePtr = head;
while (nodePtr->next)
{
nodePtr = nodePtr->next;
}
nodePtr->next = temp2;
}
}
void display()
{
linkListNode *temp = new linkListNode;
temp = head;
while (temp)
{
cout << temp->destination << " --> ";
temp = temp->next;
}
cout << endl;
}
int size()
{
linkListNode *temp = head;
int sizer = 0;
while (temp)
{
sizer++;
temp = temp->next;
}
return sizer;
}
};
class edge
{
public:
int origin;
linkList final;
bool visited;
edge()
{
//origin = NULL;
//cost=0;
visited=false;
}
};
class graph
{
private:
vector <edge> vectorOfEdges;
int vertices;
public:
graph(int v)
{
vertices = v;
vectorOfEdges.clear();
}
void addRoute(int ori, int dest)
{
int counter = 0;
for (int i = 0; i<vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin== ori)
{
counter = 1; // means element was present in the list
e.final.insert(dest);
}
vectorOfEdges[i] = e;
}
if (counter == 0) // when counter is set to zero, this means that the element was not found in the vector and needs to be pushed
{
edge e;
e.origin = ori;
e.final.insert(dest);
vectorOfEdges.push_back(e);
}
}
void printGraph()
{
edge e;
for (int i = 0; i<vectorOfEdges.size(); i++)
{
e = vectorOfEdges[i];
cout << e.origin << ":- ";
e.final.display();
cout << endl;
}
}
int sizeOfEdge(edge e)
{
int x = e.final.size() + 1;
return x;
}
int max(int one, int two)
{
if (one > two)
{
return one;
}
else
{
return two;
}
}
void BFS(int start)
{
edge e;
queue <int> q;
int save_index=0;
for (int i=0;i<vectorOfEdges.size();i++)
{
e=vectorOfEdges[i];
if (e.origin == start)
{
save_index=i;
q.push(e.origin);
e.visited=true;
break;
}
}
while (!q.empty())
{
int x=q.front();
cout << x << " " ;
q.pop();
linkListNode *l = e.final.head;
while (l)
{
if (l->visited == false)
{
q.push(l->destination);
l->visited=true;
l=l->next;
}
else
{
l=l->next;
}
}
}
}
};
int main()
{
graph g(4);
g.addRoute(0, 1);
g.addRoute(0, 2);
g.addRoute(1, 2);
g.addRoute(2, 0);
g.addRoute(2, 3);
// g.printGraph();
//cout << "Following is Breadth First Traversal (starting from vertex 2) \n";
g.BFS(1);
}
Your code is only running for the node that you have provided as the starting value for your BFS traversal.
void BFS(int start)
{
queue<int> q;
bool startFound = false;
for (int i = 0; i < vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin == start)
{
q.push(e.origin);
check.push_back(e.origin);
e.visited = true;
startFound = true;
break;
}
}
if (!startFound)
{
cout << "Start vertex not found in the graph" << endl;
return;
}
while (!q.empty())
{
int x = q.front();
cout << x << " ";
q.pop();
for (int i = 0; i < vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin == x)
{
linkListNode *l = e.final.head;
while (l != NULL)
{
bool found = false;
if (l->visited == false)
{
l->visited = true;
for (int i = 0; i < check.size(); i++)
{
if (check[i] == l->destination)
{
found = true;
break;
}
}
if (found == false)
{
check.push_back(l->destination);
q.push(l->destination);
}
}
l = l->next;
}
}
}
}
}
Instead, do this to run it for every node.