I am using Visual Studio 2013, running on windows 7 64 bit.
I am trying to display a language different than English. My code is:
#include <iostream>
#include <string>
using namespace std;
typedef char byte;
byte text[] = "текст";
int text_len;
struct Huf {
byte id;
int wh;
Huf *left, *right;
};
struct List {
List *next;
Huf *tree;
};
List *head;
char code[256];
void createList();
void writeList();
void delList(List *);
void addList(Huf *);
Huf *findDels();
void createTree();
void rlrootTree(Huf *, unsigned);
int main()
{
text_len = strlen(text);
createList();
writeList();
createTree();
cout << "writeCodes\n";
rlrootTree(head->tree, 0);
cout << endl;
system("pause");
return 0;
}
void createList()
{
int i;
int ch[256] = { 0 };
for (i = 0; i<text_len; i++) ch[text[i]]++;
List *l;
Huf *h;
head = 0;
for (i = 0; i<255; i++) if (ch[i]>0)
{
h = new Huf;
h->id = i; h->wh = ch[i];
h->left = 0; h->right = 0;
l = new List;
l->tree = h;
l->next = head; head = l;
}
}
void writeList()
{
cout << "writeList\n";
List *l = head;
while (l)
{
cout << (l->tree)->id << " ";
l = l->next;
}
cout << endl;
l = head;
while (l)
{
cout << (l->tree)->wh << " ";
l = l->next;
}
cout << endl;
}
void delList(List *l)
{
List *lp, *lc;
if (l == head) { head = l->next; delete l; }
else
{
lp = head; lc = lp->next;
while (lc != l) { lp = lc; lc = lc->next; }
lp->next = lc->next; delete lc;
}
}
void addList(Huf *h)
{
List *l = new List;
l->tree = h;
l->next = head;
head = l;
}
Huf *findDels()
{
List *l = head, *sm = head;
Huf *h;
while (l)
{
if ((l->tree)->wh < (sm->tree)->wh) sm = l;
l = l->next;
}
h = sm->tree;
delList(sm);
return h;
}
void createTree()
{
Huf *h, *h1, *h2;
while (head->next)
{
h1 = findDels();
h2 = findDels();
h = new Huf;
h->id = ' '; h->wh = h1->wh + h2->wh;
h->left = h1; h->right = h2;
addList(h);
}
}
void rlrootTree(Huf *h, unsigned index)
{
if (h)
{
code[index] = '0';
rlrootTree(h->right, index + 1);
if (h->left == 0)
{
code[index] = '\0';
cout << h->id << "->" << code << " ";
}
code[index] = '1';
rlrootTree(h->left, index + 1);
}
}
I have tried adding <locale> and <windows.h> includes with AnsiToOem() but it doesnt seem to compile - I get character errors.
You are iterating through the text byte by byte. But each letter (grapheme) consists of two code units, that is two bytes.
To make this simple I would store the string as an array of char32_t, because then the whole codepoint (one grapheme) would fit in one element of the array.
If you want to be able to handle absolutely every international "character" you would also have to handle grapheme clusters then you would have have a look at the ICU library or similar.
A dangerously simplified suggestion:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
typedef char32_t byte;
byte text[] = U"текст";
int text_len;
struct Huf {
byte id;
int wh;
Huf *left, *right;
};
struct List {
List *next;
Huf *tree;
};
List *head;
char code[16000];
void createList();
void writeList();
void delList(List *);
void addList(Huf *);
Huf *findDels();
void createTree();
void rlrootTree(Huf *, unsigned);
unsigned strlen(char32_t* st) {
unsigned len = 0;
while (*(st+len) != 0) ++len;
return len;
}
int main()
{
text_len = strlen(text);
std::cout << "len = " << text_len << std::endl;
createList();
writeList();
createTree();
cout << "writeCodes\n";
rlrootTree(head->tree, 0);
cout << endl;
system("pause");
return 0;
}
void createList()
{
int i;
int ch[16000] = { 0 }; //you really need more here
for (i = 0; i<text_len; i++) ch[text[i]]++;
List *l;
Huf *h;
head = 0;
for (i = 0; i<16000; i++) if (ch[i]>0)
{
h = new Huf;
h->id = i; h->wh = ch[i];
h->left = 0; h->right = 0;
l = new List;
l->tree = h;
l->next = head; head = l;
}
}
void writeList()
{
cout << "writeList\n";
List *l = head;
while (l)
{
cout << (l->tree)->id << " ";
l = l->next;
}
cout << endl;
l = head;
while (l)
{
cout << (l->tree)->wh << " ";
l = l->next;
}
cout << endl;
}
void delList(List *l)
{
List *lp, *lc;
if (l == head) { head = l->next; delete l; }
else
{
lp = head; lc = lp->next;
while (lc != l) { lp = lc; lc = lc->next; }
lp->next = lc->next; delete lc;
}
}
void addList(Huf *h)
{
List *l = new List;
l->tree = h;
l->next = head;
head = l;
}
Huf *findDels()
{
List *l = head, *sm = head;
Huf *h;
while (l)
{
if ((l->tree)->wh < (sm->tree)->wh) sm = l;
l = l->next;
}
h = sm->tree;
delList(sm);
return h;
}
void createTree()
{
Huf *h, *h1, *h2;
while (head->next)
{
h1 = findDels();
h2 = findDels();
h = new Huf;
h->id = ' '; h->wh = h1->wh + h2->wh;
h->left = h1; h->right = h2;
addList(h);
}
}
void rlrootTree(Huf *h, unsigned index)
{
if (h)
{
code[index] = '0';
rlrootTree(h->right, index + 1);
if (h->left == 0)
{
code[index] = '\0';
cout << h->id << "->" << code << " ";
}
code[index] = '1';
rlrootTree(h->left, index + 1);
}
}
Related
#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.
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 have a little problem with dijkstra print path, it's working on small graph size like 10-20 etc. On 100 there is problem, because printing loop going to infinity, when I've tried recurrence method, VS is showing me exepction throw, stack overflow (same problem like up ^). Do u know guys how to repair it ? There is my code.
#include <stdio.h>
#include <iostream>
#include <limits.h>
#include <conio.h>
using namespace std;
struct graphNode {
int weight;
int v;
graphNode *next;
};
class Graph {
public:
graphNode *head, *tail;
int size, vIndex;
int currentWeight;
char type;
void addNode(int v_temp, int v_weight) {
graphNode *temp = new graphNode;
temp->next = nullptr;
if (head == nullptr) {
temp->v = v_temp;
temp->weight = v_weight;
head = temp;
}
else {
tail->next = temp;
temp->v = v_temp;
temp->weight = v_weight;
}
size++;
tail = temp;
}
// GET SET METHODS
char returnType() {
return type;
}
int returnCurrentWeight() {
return currentWeight;
}
void setCurrentWeight(int weight) {
currentWeight = weight;
}
void setVIndex(int temp) {
vIndex = temp;
}
void setType(char type_temp) {
type = type_temp;
}
// Constructor
Graph() {
head = nullptr;
tail = nullptr;
vIndex = 0;
size = 0;
currentWeight = 0;
}
};
struct heapNode {
int v;
int distance;
};
class Heap {
private:
Graph *graphArray;
heapNode **heapArray;
heapNode *root;
int vNumber, size;
int *position, *parent;
public:
heapNode *addEdge(int temp_v, int temp_distance) {
heapNode *temp = new heapNode;
temp->v = temp_v;
temp->distance = temp_distance;
return temp;
}
graphNode *returnVertexHead(int i) {
return graphArray[i].head;
}
char returnType(int i) {
return graphArray[i].returnType();
}
int *returnParent() {
return parent;
}
int returnWeight(int i) {
return graphArray[i].returnCurrentWeight();
}
void setWeight(int i, int weight) {
graphArray[i].setCurrentWeight(weight);
}
bool isInHeap(int temp_v) {
if (position[temp_v] < vNumber) return true;
return false;
}
bool isEmpty(int vNumber) {
if (vNumber == 0) return true;
return false;
}
void decrestDistans(int temp_v, int temp_distance) {
int index = position[temp_v];
heapNode *temp;
heapArray[index]->distance = temp_distance;
while (index && (heapArray[index]->distance < heapArray[(index - 1) / 2]->distance)) {
position[heapArray[index]->v] = (index - 1) / 2;
position[heapArray[(index - 1) / 2]->v] = index;
temp = heapArray[index];
heapArray[index] = heapArray[(index - 1) / 2];
heapArray[(index - 1) / 2] = temp;
index = (index - 1) / 2;
}
}
heapNode *removeMin() {
if (vNumber == 0) return nullptr;
root = heapArray[0];
heapArray[0] = heapArray[vNumber - 1];
position[root->v] = vNumber - 1;
position[heapArray[vNumber - 1]->v] = 0;
--vNumber;
repairHeapDown(0);
return root;
}
void repairHeapDown(int index) {
heapNode *temp;
int parentIndex = index;
int left = index * 2 + 1;
int right = index * 2 + 2;
if (left <= vNumber && heapArray[parentIndex]->distance > heapArray[left]->distance) parentIndex = left;
if (right <= vNumber && heapArray[parentIndex]->distance > heapArray[right]->distance) parentIndex = right;
if (index != parentIndex) {
position[heapArray[parentIndex]->v] = index;
position[heapArray[index]->v] = parentIndex;
temp = heapArray[index];
heapArray[index] = heapArray[parentIndex];
heapArray[parentIndex] = temp;
repairHeapDown(index);
}
}
int dijkstra(int start, int target) {
int *distance = new int[vNumber];
int i, v, weight;
graphNode *current_graph;
heapNode *current_heap;
for (int i = 0; i < vNumber; i++)
{
distance[i] = INT_MAX;
heapArray[i] = addEdge(i, distance[i]);
position[i] = i;
parent[i] = 0;
}
parent[start] = -1;
heapArray[start] = addEdge(start, distance[start]);
position[start] = start;
distance[start] = 0;
decrestDistans(start, distance[start]);
while (!isEmpty(vNumber)) {
current_heap = removeMin();
i = current_heap->v;
if (i == target) {
int temp = 2 * distance[target];
parent[v] = i;
delete[] position;
delete[] distance;
delete[] heapArray;
return temp;
}
current_graph = returnVertexHead(i);
while (current_graph != nullptr) {
v = current_graph->v;
weight = current_graph->weight + returnWeight(i) + distance[i];
if (weight < distance[v]) {
distance[v] = weight;
decrestDistans(v, distance[v]);
parent[v] = i;
}
current_graph = current_graph->next;
}
}
return 0;
}
Heap(Graph *table, int temp_vNumber) {
vNumber = temp_vNumber;
size = temp_vNumber;
root = nullptr;
heapArray = new heapNode*[size];
position = new int[size];
parent = new int[size];
graphArray = table;
}
~Heap() {
delete[] parent;
}
};
void printPath(int *parent, int start, int target)
{
int current = target;
while (current != start) {
cout << current << " ";
current = parent[current];
}
cout << current << " ";
}
int main() {
int n, time_knight, patch_number, temp_v, temp_weight, i,
home_index, gral_index, ni_index, ni_weight, krzak_index;
char type;
gral_index = home_index = ni_index = krzak_index = 0;
i = 0;
cin >> n >> time_knight;
Graph *table = new Graph[n];
while (1) {
cin >> type;
table[i].setType(type);
if (type == '5') gral_index = i;
if (type == '4') home_index = i;
if (type == '3') ni_index = i;
if (type == '2') table[i].setCurrentWeight(time_knight);
if (type == '1') krzak_index = i;
cin >> patch_number;
for (int j = 0; j < patch_number; j++)
{
cin >> temp_v >> temp_weight;
table[i].setVIndex(i);
table[i].addNode(temp_v, temp_weight);
}
i++;
if (i == n) break;
}
Heap *object = new Heap(table, n);
Heap *object2 = new Heap(table, n);
ni_weight = object->dijkstra(ni_index, krzak_index);
table[ni_index].setCurrentWeight(ni_weight);
cout << endl << endl << endl;
printPath(object->returnParent(), ni_index, krzak_index);
cout << endl << endl << endl;
object2->dijkstra(home_index, gral_index);
printPath(object2->returnParent(), home_index, gral_index);
_getch();
return 0;
}
I have two problems where I'm having a hard time to understand.
1) I'm having a hard time to understand how to pass my L1 doublyLinkedList into an array so that I can save each list of numbers my txt file reads
2) If I have an uneven negative number my break_into_nodes() method is reading an error as stoi is creating 1 node for a negative sign, how would I create an if statement to continue to breaking it into a node
#include "stdafx.h"
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <cstdlib>
#include "ArgumentManager.h"
using namespace std;
struct Node
{
long long value;
Node *next, *prev;
Node(long long y)
{
value = y;
next = prev = NULL;
}
};
class doubleLinkedList
{
Node *back;
public:
Node *front;
doubleLinkedList() { front = NULL; back = NULL; }
~doubleLinkedList() { destroyList(); }
doubleLinkedList(const string& num, int digitsPerNode) {
appendNodeFront(stoi(num, 0, 10));
}
void appendNodeFront(long int x);
void dispNodesForward(int digits);
void destroyList();
void clean();
};
void doubleLinkedList::clean()
{
destroyList();
}
void doubleLinkedList::appendNodeFront(long int x)
{
Node *n = new Node(x);
if (front == NULL)
{
front = n;
//back = n;
}
else
{
front->prev = n;
n->next = front;
front = n;
}
}
void doubleLinkedList::dispNodesForward(int digits)
{
Node *temp = front;
int temp_val;
if (temp != NULL)
{
/* First node does not get Zero padding */
temp_val = (int)temp->value;
printf("%d", temp_val);
temp = temp->next;
while (temp != NULL)
{
temp_val = (int)temp->value;
printf("%0*d", digits, temp_val);
temp = temp->next;
}
}
}
void doubleLinkedList::destroyList()
{
Node *T = back;
while (T != NULL)
{
Node *T2 = T;
T = T->prev;
delete T2;
}
front = NULL;
back = NULL;
}
void break_into_nodes(doubleLinkedList *list, string number, int digits) {
string node_value;
int num_index, num_iterations;
int i, j;
num_index = number.length();
if (num_index < digits)
{
node_value = number;
list->appendNodeFront(stoi(node_value));
}
else {
/* adjust for incomplete nodes */
if ((number.length() % digits) == 0)
num_iterations = (number.length() / digits);
else
num_iterations = (number.length() / digits) + 1;
for (j = 0; j < num_iterations; j++) {
node_value.clear();
for (i = 0; i < digits; i++) {
num_index--;
if (num_index < 0)
break;
node_value = node_value.insert(0, number.substr(num_index, 1));
}
list->appendNodeFront(stoi(node_value));
}
}
}
// Driver program
int main(int argc, char* argv[]) {
doubleLinkedList l1;
if (argc < 2) {
cerr << "Usage: infinitearithmetic \"input=xyz.txt;digitsPerNode= <number>\"\n";
}
ArgumentManager am(argc, argv);
string filename = am.get("input");
/* Digits per Node ar from 1 to 8 */
int digitsPerNode = stoi(am.get("digitsPerNode"));
ifstream ifs(filename.c_str());
string line;
string num1;
int i = 0;
while (!ifs.eof())
{
getline(ifs, line);
//cout << "" << line << endl;
num1 = line;
break_into_nodes(&l1, num1, digitsPerNode);
l1.dispNodesForward(digitsPerNode);
cout << endl;
l1.clean();
i++;
}
return 0;
}
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.