HELP! I'm trying to create a hash table using Separate Chaining. For some unknown reason I cant seem to traverse and find all the original int I loaded. I suspect the modulo function is giving me bad addresses sometimes in both functions. First creating bad addresses on assorted int when creating the hash table and then sometimes searching the wrong addresses in the second function while attempting to traverse and confirm my list using modulo again. The hash table is populated by a basic random array of numbers and then I compare the created hash table with the original random array of int. Here is what I believe the culprit is causing all my troubles but I cant be 100% sure:
address = randARRAY[key] % MAX_KEYS;
And here is the function for creating the Hash Table using Separate Chaining. I generally have MAX_KEYS = 5000, tbSIZE = 8989, which is better than 75% Load factor somewhere around 55%:
void separateCHAINING(int *randARRAY,int tbSIZE,TABLE *head[]){
int key = 0,
address = 0,
collisions = 0,
newONE = 0;
randARRAY[MAX_KEYS + 1] = 0;
TABLE *newADDRESS[tbSIZE];
newADDRESS[tbSIZE] = new TABLE();
for(int a = 0; a < tbSIZE; a++){
newADDRESS[a] = NULL;
head[a] = NULL;
}
while(randARRAY[key] != 0){
address = randARRAY[key] % MAX_KEYS;
newADDRESS[address] = new TABLE;
newADDRESS[address]->key = randARRAY[key];
if(head[address] != 0){
newADDRESS[address]->next = head[address]->next;
head[address]->next = newADDRESS[address];
collisions++;
}
else{
newADDRESS[address]->next = head[address];
head[address] = newADDRESS[address];
newONE++;
}
key++;
}
cout << "total collisions: " << collisions << endl;
cout << "new: " << newONE << endl;
cout << "added: " << collisions + newONE << endl;
cout << "key: " << key << endl;
}
This created data appears to be passed without issue. I used gdb to create a ridiculously long list on one array index and it was all there in the second function without missing any nodes. This is why I think the addresses might be getting botched by modulo in both the function above and on this one below. This is apparently creating bogus addresses and then calling the wrong ones later. In the end Im never able to find all my int for the random array put in the Hash Table. Here is the function which uses modulo again and then tries to traverse and match the random array against the new hash table:
void tableTWO_MATCH(int *randARRAY,TABLE *HT_TWO[]){
int key = 0,
address = 0,
match = 0,
nomatch = 0;
randARRAY[MAX_KEYS + 1] = 0;
while(randARRAY[key] != 0){
address = randARRAY[key] % MAX_KEYS;
while(HT_TWO[address]->next != NULL && HT_TWO[address]->key != randARRAY[key]){
HT_TWO[address] = HT_TWO[address]->next;
}//end second while
if(HT_TWO[address]->key == randARRAY[key]){
match++;
}//end if
if(HT_TWO[address]->key != randARRAY[key]){
nomatch++;
}//end if
key = key + 1;
address = 0;
}//end outer while
cout << "match: " << match << endl;
cout << "not match: " << nomatch << endl;
cout << "key: " << key << endl;
}
As always thank you ahead of time for any assistance! I will be grateful if you can see where I'm messing up!
Well I guess I'm just a bone head! I used a boolean variable to check and see if a match was found at any point in time during traversal.
if(HT_TWO[address]->key == randARRAY[key]){
found = true;
}
I was trying to match nodes that had traversed past their match and getting poor results. Anyway This is how I changed my verification using boolen instead. Thanks for your help guys!
void tableTWO_MATCH(int *randARRAY,TABLE *HT_TWO[]){
int key = 0,
address = 0,
match = 0,
nomatch = 0;
bool found = false;
randARRAY[MAX_KEYS + 1] = 0;
while(randARRAY[key] != 0){
address = HASH(randARRAY[key],MAX_KEYS);
if(HT_TWO[address]->key == randARRAY[key]){
match++;
}
else{
while(HT_TWO[address]->next != NULL){
HT_TWO[address] = HT_TWO[address]->next;
if(HT_TWO[address]->key == randARRAY[key]){
found = true;
}
}//end second while
if(found == false){
nomatch++;
}
}
key = key + 2;
}//end outer while
cout << "not match: " << nomatch << endl;
cout << "key: " << key << endl;
}
Related
I have created a program that will read a text file and put the words as strings into a linked list, along with their frequency count throughout the text file. It only prints one occurrence of each word with the total times it appeared.
My program also loads a blacklist, in which it is supposed to compare the blacklist linked list to the word cloud (or word frequency) linked list, and then remove the blacklisted words from the word frequency list.
I have tried doing this several ways. The following is my 3rd version. What I am wanting to do is add a Boolean value to each node, and when one node is equal to a word in the blacklist, the Boolean value will be true. However, I am not getting it to print right with the following code. I have searched, and I can't seem to find the correct syntax to add a Boolean value to a node in linked list.
EDIT #3:
void wordCloud::compareWith(wordCloud& wordList, wordCloud& badList){
wordNode *wordListTemp, *blacklistTemp, *temp = NULL;
unsigned int counter = 0;
for (blacklistTemp = badList.head; blacklistTemp; blacklistTemp = blacklistTemp->next){
cout << blacklistTemp->myWord << "\n";
for (wordListTemp = wordList.head; wordListTemp; wordListTemp = wordListTemp->next){
if (wordListTemp->myWord != blacklistTemp->myWord){
wordListTemp->blacklist = false;
if (wordListTemp->blacklist = false){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
}
}
else if (wordListTemp->myWord == blacklistTemp->myWord){
cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
wordListTemp->blacklist = true;
if (wordListTemp->blacklist = true)
cout << wordListTemp->myWord << "\n";
}
}
//counter++;
cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
}
system("pause");
}
This is not complete, but it is as far as I have gotten. The problem is it only prints the true if, and will not print any false if. Even if I switch the values, it will still only print the true if's. So I am assuming that I am going about this wrong. What would be the correct way to "flag" a node true and "flag" a node false? All the cout's are for debugging purposes. I will remove or comment those out later.
First of all, you could always debug step-by-step to see just which portion of the code freezes up your comp. The better way to detect memory leaks would be to use Valgrind.
On a side note, I would implement that comparison function as a comparison operator, and implement a comparison operator for their Nodes as well (for convenience). Doing so divides the code a bit and helps, later on, understand where your problem is. It is also a better way to do it (more readable, OOP-y, etc).
Finally!!
With a lot of old fashion debugging and cout statements, I finally got what I wanted. I know this might have been easy for some, but with not being very familiar with linked lists, this was quite the process for me.
Before I was trying to delete words that were seen in the blacklist linked list out of the wordList linked list. I decided later to just try to add a boolean value of true to the nodes in wordList, and then adjust my print function to not print nodes with the value of true. I also had to tweak a few things in insertWord(), and my freqSort() functions, but all that really consisted of was adding a pointer to the boolean value when a new node was being created.
My member function is void wordCloud::compareWith(wordCloud& wordList, wordCloud& badList), and is part of my wordCloud class. Here is the following definition:
void wordCloud::compareWith(const wordCloud& wordList, const wordCloud& badList){
wordNode *wordListTemp, *blacklistTemp;
unsigned int counter = 0;
//loop that advances wordListTemp
for (wordListTemp = wordList.head; wordListTemp; wordListTemp = wordListTemp->next){
blacklistTemp = badList.head;
//loop advances blacklistTemp - compares links in wordList to badList(blacklist)
//and sets the node to true if myWord equals any word in the blacklist
while (blacklistTemp){
if (wordListTemp->myWord == blacklistTemp->myWord){
wordListTemp->blacklist = true;
counter++;
}
blacklistTemp = blacklistTemp->next;
}
//for debugging
//cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
}
/********************* All for debugging ***************************************
cout << "True:\n\n";
wordListTemp = wordList.head; //reset wordListTemp to head
while (wordListTemp){ //print blacklisted words from wordList
if (wordListTemp->blacklist == true){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
}
wordListTemp = wordListTemp->next;
}
//prints total words blacklisted
cout << "There are " << counter << " blacklisted words.";
cout << "\n\nFalse:\n\n";
wordListTemp = wordList.head; //reset wordListTemp to head
counter = 0;
while (wordListTemp){ //print non-blacklisted words from wordList
if (wordListTemp->blacklist == false){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
counter++;
}
wordListTemp = wordListTemp->next;
}
//prints total words not blacklisted
cout << "There are " << counter << " words that are not blacklisted.\n";
system("pause");
******************** End debugging *******************************************/
}
So basically this is a comparison function that flags nodes that are found in another list. Works well and tested with all other options.
I have a std::set of strings and I want to iterate over them, but the iterator is behaving differently for different sizes of set. Given below is the code snippet that I'm working on:
int test(set<string> &KeywordsDictionary){
int keyword_len = 0;
string word;
set<string>::iterator iter;
cout << "total words in the database : " << KeywordsDictionary.size() << endl;
for(iter=KeywordsDictionary.begin();iter != KeywordsDictionary.end();iter++) {
cout << *iter;
word = *iter;
keyword_len = word.size();
if(keyword_len>0)
Dosomething();
else
cout << "Length of keyword is <= 0" << endl;
}
cout << "exiting test program" << endl;
}
The code is working properly & *iter is being dereferenced & assigned to word until the size of KeywordsDictionary is around 15000. However when the size of KeywordsDictionary increases beyond 15000,
the print statement cout << *iter; is printing all the contents of KeywordsDictionary correctly.
but the pointer to the iterator *iter is not being dereferenced & not being assigned to word. word is just being an empty string.
EDIT: And the output of the program is :
total words in the database : 22771
�z���AAAADAAIIABABBABLEABNABOUTACACCEPTEDACCESSACCOUNT...
Length of keyword is <= 0
exiting test program
So basically, I'm guessing the loop is executing only once.
Try to declare keyword_len as
std::string::size_type keyword_len = 0;
instead of
int keyword_len = 0;
org.proto
message Optimize {
required int element_size = 1;
required string element_name = 2;
}
message nodes {
repeated Optimize = 1;
}
Have this decoding function:
DecodeNodeMsg(char *msg, int size)
{
Org::nodes node;
int element_size;
string element_name;
int NumofElem = 0;
node.ParseFromArray((void *)msg, size);
for (int i = 0; i < nodes.Optimize().size(); i++)
{
element_size = nodes.Optimize(i).element_size();
element_name = nodes.Optimize(i).element_name();
cout << "size" << element_size << endl;
cout << "name" << element_name << endl;
NumofElem++;
}
cout << "number of" << NumofElem << endl;
}
I am encoding a nodes message with three Optimize messages in it. and calling this decode function. Encoding part is an old code which is working fine from long time. So i dont suspect the encoding function.
In the decode function, I see that the NumofElem is correctly printed as three. However, i see that both element_size & element_name are just garbage. Integer has some junk value and string has a binary data.
I am having this issue only if this repeated fields. If fields are required/optional fields, then i dont have this issue.
Could some one has similar issue... ? if so any clues on how to fix this ?
Thanks,
Kiran
I don't see where you are actually decoding a message. I see you creating a new node object, but then calling Org::nodes() which looks wrong. I think you need to access the Optimize elements like this:
for (int i = 0; i < node->optimize_size(); i++)
{
element_size = node->optimize(i).element_size();
element_name = node->optimize(i).element_name();
cout << "size" << element_size << endl;
cout << "name" << element_name << endl;
NumofElem++;
}
But again I think your nodes object needs to be decoded from something. The mutable methods allow you to set data. There's also the ParseFrom methods. Also in my proto files I number the elements in a message. See https://developers.google.com/protocol-buffers/docs/overview
message nodes {
repeated Optimize = 1;
}
The function deserializes the buffer into the local variable node, but the loop references nodes. I'd also validate the return value from ParseFromArray.
I'm writing a code to index the skills available to a user in a game, constructed as a linked list. I've throughly tested the function that populates the list and it seems to be working correctly (so the head pointer for the list shouldn't be null). When I attempt to traverse the list to set values in the skill, before any of the code which writes to memory within the list gets to execute the program is crashing when I initialise the temp pointer within the search function of the list to the head pointer.
What makes this additionally weird to me is that it worked fine (and I had tested this fairly thuroughly) until I added in a list to store a list of available items, and may just be missing an odd interaction between the two when I populate them.
The specific error is that the pointer is supposedly accessing memory index 0x000000c to write to, but I don't see how the code at that point is dealing with a null pointer at all (since after 10 runs of the program the OS shouldn't be allocating that block of memory to the temp pointer every time and nothing else should be null.
I'm probably just ramblind at this point so here's the code:
The function that causes the error according to the debugger:
void Mechanics::setSkillValue(int index, int value)
{
Skill *temp = FirstSkill; // << The error is happening on this line //
while((temp != NULL)&&(temp->index != index))
{
temp = temp->next;
}
if (temp == NULL)
{
cout << "%";
}
else temp->setValue(value);
// cout << temp->returnValue(); //This was a test check, not needed for anything
}
The Function that's supposed to populate the skill and item lists.
void Mechanics::Populate()
{
ifstream skillstream("Skills.txt");
if(skillstream.is_open())
{
while(skillstream.good())
{
Skill *newskill;
int indexval;
string skillindex;
string skillname;
string skilldescription;
cout << "TP4" << endl; //TEST POINT
getline(skillstream, skillindex);
cout << skillindex;
getline(skillstream, skillname);
cout << skillname;
getline(skillstream, skilldescription);
cout << skilldescription; cout << endl;
indexval = atoi(skillindex.c_str());
newskill = new Skill(skillname, skilldescription,indexval);
//cout << "TP5" << endl; //TEST POINT
if(newskill == NULL) cout << "NULL!!!";
addSkill(newskill);
}
}
ifstream itemstream("Items.txt");
if(itemstream.is_open())
{
while(itemstream.good())
{
Item *newitem;
int indexval;
string skillindex;
string skillname;
string skilldescription;
string abilitydescription;
string valueSTR;
string typeSTR;
int value;
int type;
int numeric[5];
// cout << "TP4" << endl; //TEST POINT
getline(itemstream, skillindex);
// cout << skillindex;
getline(itemstream, skillname);
// cout << skillname;
getline(itemstream, skilldescription);
// cout << skilldescription;
getline(itemstream, abilitydescription);
getline(itemstream, valueSTR);
value = atoi(valueSTR.c_str());
getline(itemstream,typeSTR);
type = atoi(typeSTR.c_str());
for (int i=0; i < 5; i++)
{
string numericSTR;
getline(itemstream,numericSTR);
numeric[i]=atoi(numericSTR.c_str());
}
indexval = atoi(skillindex.c_str());
newitem = new Item(indexval, skilldescription, skillname, abilitydescription, value, type, numeric);
//cout << "TP5" << endl; //TEST POINT
// if(newskill == NULL) cout << "NULL!!!";
addItem(newitem);
}
}
The function that's supposed to actually add a skill to the skill list:
void Mechanics::addSkill(Skill *nskill)
{
Skill *temp = FirstSkill;
if(FirstSkill == NULL)
{
FirstSkill = nskill;
//cout << "TP1" << endl; //TEST POINT
//FirstSkill->printname();
}
else
{
while((temp->next != NULL))
{
temp = temp-> next;
//cout << "TP2" << endl; //TEST POINT
//temp->printname(); cout << endl;
}
if (FirstSkill != NULL)
{
temp->next = nskill;
nskill->next = NULL;
}
}
}
The code that I have is somewhat extensive so I'm only going to include the blocks which are potentially interacting with the function that's throwing up the error.
Thanks in advance for reading through this, and any assistance you're able to offfer, I've been banging my head against this for about 6 hours now and I've lost the perspective to actually track this one down.
Let's see I want to do this, i want to get the parent of a tree, then sum the nodes and putthe result in the parent, this is multithreaded. I'm using a queue to stare the nodes thata can be sum, etc.
The problem I'm facing is this
error: no match for call to ‘(Triplets) (int&, int&, bool&, NodeT*&)’
The code is coming from is this
void find_triplets(NodeT *ptrRoot)
{
if (ptrRoot != NULL)
{
find_triplets(ptrRoot->left);
find_triplets(ptrRoot->right);
cout << "find triplets and save them to the queue" << endl;
cout << " we hit a hot spot is null the root, nothing to see here move along boys" << endl;
if(ptrRoot->left != NULL && ptrRoot->right != NULL)
{
if (ptrRoot->left->done == true && ptrRoot->right->done == true)
{
cout << "we got one of 2 sons true so do something, this are the sons "
<< ptrRoot->left->key_value << " " << ptrRoot->right->key_value << endl;
cout << "sum them and put it in the father and set it to true " << endl;
ptrRoot->key_value = ptrRoot->left->key_value + ptrRoot->right->key_value;
ptrRoot->done = true;
cout << "thread queue " << endl;
triplet(ptrRoot->left->key_value, ptrRoot->right->key_value, ptrRoot->done, ptrRoot);
qThreads.push(triplet);
}
}
}
The triplet class is like so
class Triplets
{
public:
int nVal1;
int nVal2;
NodeT *ptrNode;
bool bUpdate;
Triplets()
{
nVal2 = 0;
nVal1 = 0;
bUpdate = false;
ptrNode = NULL;
}
~Triplets()
{
delete ptrNode;
}
Triplets(int nVal1, int nVal2, bool bUpdate, NodeT *ptrNode)
{
this->nVal2 = nVal2;
this->nVal1 = nVal1;
this->bUpdate = bUpdate;
this->ptrNode = ptrNode;
}
void form_triplet(int nval1, int nVal2, bool bUpdate, NodeT *ptrNode)
{
this->nVal2 = nVal2;
this->nVal1 = nVal1;
this->bUpdate = bUpdate;
this->ptrNode = ptrNode;
}
};
So what I want to do is to store the actual object in the queue to modify it, and don't make copies of it. Thanks
It appears that triplet in your find_triplets function is a Triplets instance. The compiler interprets that line, therefore, as an attempt to invoke its operator() function using those four arguments, but your Triplets class has no such operator, so you get the error message reported above.
You probably meant either to declare another Triplets variable (named triplet), or to call triplet.form_triplet instead of triplet.operator().
Triplets triplet(ptrRoot->left->key_value, ptrRoot->right->key_value, ptrRoot->done, ptrRoot);
// or
triplet.form_triplet(ptrRoot->left->key_value, ptrRoot->right->key_value, ptrRoot->done, ptrRoot);