Hash table(linear probing) - c++

I am making a hash table using linear probing and i have to resize the array when ever the load factor i.e (no. of elements entered in hashtable)/(size of hashtable), becomes greater than 0.5, i have to resize the array.I am doing the resizing by initializing a pointer in a class which contains functions related to hashtable.I am putting the pointer equal to an array of a struct (struct only contains a string) of size 100.every time load factor becomes greater than 0.5, i resize the array by making a new array of double the previous size and point the pointer to the new array.I also have an int which stores current size of array and which is updated with every instance in which resize function is used.The number of elements inserted are incremented with every call to insert function.Am I doing this correctly?Below is my code
#include <cstring>
#include <vector>
#include <math.h>
#include <iomanip>
using namespace std;
int power(int a,int b)
{
for (int i=0;i<b;i++)
{
a*=a;
}
return a;
};
struct Bucket
{
string word;
};
const int size=100;
class LProbing
{
private:
int a; //a constant which is used in hashing
int cursize; //current size of hash table
Bucket *Table; //pointer to array of struct
int loadfactor; //ratio of number of elements entered over size of hashtable
int n; //number of elements entered
Bucket table[size]; //array of structs
public:
LProbing(int A); //constant is decided by user
void resize();
void insert(string word);
void Lookup(string word);
};
LProbing::LProbing(int A)
{
cursize=size;
a=A;
Table=table;
loadfactor=0; //initially loadfactor is 0 as number of elements entered are 0
n=0;
}
void LProbing::resize()
{
cout<<"resize"<<endl;
loadfactor=n/cursize; //ensuring if resize needs to be done
if (loadfactor<=0.5)
{
return;
}
const int s=2*cursize;
Bucket PTable[s];
for (int i=0;i<cursize;i++)
{
if (Table[i].word.empty())
continue;
//rehashing the word onto the new array
string w=Table[i].word;
int key=0;
for (int j=0;j<w.size();j++)
{
unsigned char b=(unsigned char)w[j];
key+=(int)power(a,i)*b;
}
key=key%(2*cursize);
PTable[key].word=w; //entering the word in the new array
}
Table=PTable; //putting pointer equal to new array
cursize=2*cursize; //doubling the current size of array
}
void LProbing::insert(string word)
{
cout<<"1"<<endl;
n++; //incrementing the number of elements entered with every call to insert
//if loadfactor is greater than 0.5, resize array
loadfactor=n/cursize;
if (loadfactor>0.5)
{
resize();
}
//hashing the word
int k=0;
for (int i=0;i<word.size();i++)
{
unsigned char b=(unsigned char)word[i];
int c=(int)((power(a,i))*b);
k+=c;
cout<<c<<endl;
}
int key=0;
key=k%cursize;
cout<<key<<endl;
//if the respective key index is empty enter the word in that slot
if (Table[key].word.empty()==1)
{
cout<<"initial empty slot"<<endl;
Table[key].word=word;
}
else //otherwise enter in the next slot
{
//searching array for empty slot
while (Table[key].word.empty()==0)
{
k++;
key=k%cursize;
}
//when empty slot found,entering the word in that bucket
Table[key].word=word;
cout<<"word entered"<<endl;
}
}
#include "Linear Probing.cpp"
#include <fstream>
using namespace std;
int main()
{
LProbing H(35);
ifstream fin;
fin.open("dict.txt");
vector<string> D;
string d;
while (getline(fin,d))
{
if (!d.empty())
{
D.push_back(d);
}
}
fin.close();
for (int i=0;i<D.size();i++)
{
H.insert(D[i]);
}
system("PAUSE");
return 0;
}

You may find it helpful somewhere:
http://www.cs.rmit.edu.au/online/blackboard/chapter/05/documents/contribute/chapter/05/linear-probing.html

You are dealing with big numbers and variable "key" is overflowing in:
key += (int)power(a,i)*b

It looks like loadfactor is calculated as int/int so it will stay 0 until it reaches 1. Try casting the inputs to the division into floats.

Related

Unlimited Object Creation in C++

While learning the dynamic object creation in C++ i have encountered a doubt . Here is my code.
And my question is , when the limiting condition in the loop is same as that of the no of objects created it works fine. But what happens when the loop works for more than the size given , it seems printing the values entered , but we have created only 4 objects and changed the condition of loop to more than 4
#include <iostream>
using namespace std;
class item{
int number;
public:
item(){
cout<<"Constructor"<<endl;
}
~item(){
cout<<"Destructor"<<endl;
}
void get_num(int num){
number = num
};
void show_num(){
cout<<"Number is "<<number<<endl;
}
};
const int size=4;
int main() {
item *itemObj = new item[size];
item *d = itemObj; //copy the address of itemObj inorder to access its member functions later
int tempNum;
for (int i = 0; i < size; ++i) {
cout<<"Enter the Number"<<endl;
cin>>tempNum;
itemObj->get_num(tempNum);
itemObj++;
}
//to print the numbers entered
for (int i = 0; i < size; ++i) {
d->show_data();
d++;
cout<<d<<endl;
}
delete itemObj;
return 0;
}
Your code isn't working fine at all. Because you change the value of the pointer that you requested from the new operator. When you call the delete for the itemObj at the last line, it doesn't have its original value.
So, instead of modifying the itemObj, you should modify the copy of it which is the pointer d here. Therefore, the problem isn't about the iteration amount of the loop. It's actually the violation on the heap memory.
Also, if you're creating a dynamic array, you should call delete [] instead of delete.

Pointer, Arrays, Structs, Getchar: C++

One of the functions of my program must be to add a structure element in an array with 1000 members, in my struct stay 'matrnr' as integer,'name' with pointer as char and 'abslv' as array with 30 elements,because I must write characterstring using char and the size of the signs has to be declared, and pointer too,because the sum of all char-strings have to be smaller or equal to 30.
I am not allowed to use any library functions,only printf,getchar,scanf,cin and cout from iostream and stdio.h
My Questions about the struct:The name must also be implement with char,do I have to write array?
const int maxstudenten = 1000;
const int MAX = 30;
struct student_t {
int matrnr;
char* name[MAX];
char** abslv[MAX];
};
I have also problems in the following spaces in this function (In the comments):
int land (student_t *feld[maxstudenten], int i) { //I is my counter for
//the current size
student_t *pstudentanlegen= new student_t; //Write a new student
printf("Matrikelnummer:...."); //Enrolment number
std::cin>>pstudentanlegen->matrnr; //Stack->enrolment number
if (pstudentanlegen->matrnr>1 && pstudentanlegen->matrnr<999999) {
//the enrolment number must be >1 and <999999
if (binaeresuche(&feld[maxstudenten],i,(pstudentanlegen->matrnr))!=0) { //It examins if a student with this name already exists
std::cout<<"Student mit diesem Matrikelnummer ist schon vorhanden"<<std::endl; //Student with this enr.nr exists
return i;
}else {
printf("\nName:.....");
pstudentanlegen->name=getchar(); //Pointer->name
//Here I cant write anything although I have written getchar
std::cout<<std::endl;
int zaehler=0;
std::cout<<"Möchten Sie Lehrveranstantungen hinfügen? j=ja,n=nein"<<std::endl;
//Do you want to add lectures?
char a;
std::cin>>a;
if(a=='j' && zaehler<MAX) { //zaehler=my second counter
//for the lectures
std::cout<<"Lehrveranstaltung:"; //Lecture:
pstudentanlegen->abslv[MAX]=getchar();
//insupportable types of allocation of int to char* [30]
zaehler++;
}
i++;
} //Anhängen (sortiert nach Matrikelnummer)
//add(sorted towards number)
int position=0;
while(position<maxstudenten && pstudentanlegen->matrnr>feld[position]->matrnr) { //Invalid conversion of int in char**
position++;
}
}return i;
}

Converting String to int using stoi inside a function

I've tried multiple methods to make the stoi (or other functions) work for my needs (converting a given string to an integer for the purpose of making a key for a hash table). Specifically, I would like to ask why stoi does not like this conversion. I get the error "std::invalid_argument at memory location 0x0034F41C." I have looked around and couldn't find what I am doing wrong.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
enum EntryType { Legitimate, Empty, Deleted }; //creat new data type that holds node status
struct HashNode //create new struct with (hash node)
{
string element; // item inside node
enum EntryType info; //status
};
struct HashTable //Creates a new struct (hash table)
{
int size; //defines size of table
HashNode *table; //creates pointer to table
};
int HashFun1(std::string skey, int size) //first hash function
{
std::string key2 = skey;
int key = stoi(key2);
return key % size; // will return the inputed value
}
//int HashFunc2(string key, int size) //second hash function
//{
// return(key * size - 1) % size; //needs to convert between string and int
//}
int main()
{
cout<<HashFun1("t", 2);
}

combinations of k-tuple from n elements set by recursive

#include <vector>
#include <iostream>
using namespace std;
void SubSetNum(bool * select, int*a, int selectk, int k, int selectn, int n )// depthk to
{
if(k>n) return;
if(selectn==n)
{
if(selectk==k)
{
for(int i=0;i<n;i++)
if(select[i]==true)
cout<<a[i];
cout<<endl;
}
return;
}
select[selectk]=false;
SubSetNum(select,a,selectk,k,selectn+1,n);
select[selectk]=true;
SubSetNum(select,a,selectk+1,k,selectn+1,n);
}
int main()
{
int k=3;
int n=5;
int a[]={1,5,8,10,13};
//while(cin>>k)
{
bool *select=new bool[n];
memset(select,0,sizeof(bool)*n);
SubSetNum(select,a,0,k,0,n);
delete []select;
}
return 0;
}
This a question, that I want to get k elements from n elements set.
But it prints out incorrect answer? I am always confused when I design recursive algorithms...Especially the parameter of functions, if or not return value, and so on, thus I always try to forcely remember the code in textbook.
Your mistake is here:
select[selectk]=false;
...
select[selectk]=true;
It should be this:
select[selectn]=false;
...
select[selectn]=true;
I believe the cause of the mistake was a failure to remember what the variables represent. The variable selectn is the index of the element being included or excluded. The variable selectk is the number of elements already included. It does not make sense to use selectk as an index into a.

Swap 2D int array elements according to user input using printf and scanf

How do i swap the elements in a 2D int array according to use input? For example i have a 2x2 matrix with elements
int c[2][2]=
{
{1,2, },
{3,4, }
};
the user inputs which area to swap like: c[0][0] and c[0][1] then display the new results. Thanks
#include <stdio.h>
#include <stdlib.h>
void swap(int c[2][2],int &x1,int &y1,int &x2,int &y2)
{
int temp = c[x1][y1];
c[x1][y1] = c[x2][y2];
c[x2][y2] = temp;
}
int main(void)
{
int c[2][2]=
{
{1,2, },
{3,4, }
};
int x,y;
int x1,x2,x3,x4,x5,y1,y2,y3,y4,y5;
for(x=0;x<2;x++)
{
for(y=0;y<2;y++)
{
printf("\t%d",c[x][y]);
}
printf("\n");
}
printf("\nEnter 1st value to be swapped:\n");
printf("Row\n");
scanf("%d",&x3);
printf("Column\n");
scanf("%d",&y3);
printf("\nEnter 2nd value to be swapped:\n");
printf("Row\n");
scanf("%d",&x4);
printf("Column\n");
scanf("%d",&y4);
if((x3==1&&y3==1)&&(x4==1&&y4==2))
{
swap(c[0][0],c[0][1]);
}
for(x=0;x<2;x++)
{
for(y=0;y<2;y++)
{
printf("\t%d",c[x][y]);
}
printf("\n");
}
system("pause");
return ;
}
It looks like you just want to do this:
swap(c[x3-1][y3-1],c[x4-1][y4-1]);
But before you do that, you'll need to sanitise the variables to ensure they are within the range of the array.