Quick Hash Table using Chaining - hash

Attempting to better understand chaining on a hashtable. Seeking a simple table that hashes a value and only associates one integer to the value hashed. Here is sample code of the problem in question...
/* hash string value return int */
public int hashFunction(String D) {
char[] Thing = D.toCharArray();
for(int i=0; i < Thing.length; i++){
index += Thing[i]; }
return index % TABLE_SIZE;
}
/* hash string value return void */
public void hashFunction(String D) {
char[] Thing = D.toCharArray();
for(int i=0; i < Thing.length; i++){
index += Thing[i];}
int hash = index % TABLE_SIZE;
if(table[hash] == null){
table[hash] = new HashEntry( Level, Value );
}
else{
table[hash].setNext(nd);
}
}
/* miscellaneous code snippet */
if(table[hash] == null){
table[hash] = new HashEntry();
}
else if (Data.compareTo("VAR") == 0) {
Data = inFile.next();
char[] Thing = Data.toCharArray();
for(int i=0; i < Thing.length; i++){
hash += Thing[i];}
hash = hash % TABLE_SIZE;
hm.setIntoHashTable(hash);
Data = inFile.next();
if(Data.compareTo("=") == 0) {
Data = inFile.next();
int value = Integer.parseInt(Data);
hm.getIntoHashTable(he.setValue(value));
}
}

Well the chaining occurs when you have collision in the indexes.
Lets assume you have a TABLE_SIZE=10
Now you have to store string abc, so you get hash as 4
Now when you gonna store string cba, you end up with same hash 4
So now to store cba at the same index, you will create and store a List at index 4.
The List will contain both abc and bca. This List is called chain and this process of storing multiple values at the same hash is called Chaining.
Pseudo code look like:
if(table[hash] == null)
table[hash] = new ArrayList<HashEntry>();//APPEND ON TO THE LOCATION ALREADY THERE!
table[hash].add(new HashEntry());
The table will be declared as:
#SuppressWarnings("unchecked")
List<HashEntry>[] table = new List[TABLE_SIZE];
You might have to suppress warning as arrays and generics dont go smoothly.

Related

How to use selection sort in objects and classes

I'm creating two classes called stop watch and random numbers, which I have already done, but I needed to create a test program that would measure the execution time of sorting 100,000 numbers using selection sort. I know how to create a selection sort, I just don't know how to take the random numbers class and put it together with the selection sort, I get the error message "incompatible types random numbers cannot be converted to int" I hope someone can help me.
My random numbers class
import java.util.Random;
public class randomnumbers {
Random ran1 = new Random();
private int size;
public randomnumbers(){
size = 100000;
}
public int getSize(){
return size;
}
public void setSize(int newSize){
size = newSize;
}
public int [] createArray(int [] size){
for (int i = 0; i < size.length; i++){
size[i] = ran1.nextInt();
}
return size;
}
public static void printArray (int [] array){
for (int i = 0; i < array.length; i++){
if (i < 0){
System.out.println(array[i] + " ");
}
}
}
}
My test Program
public static void main (String [] args){
// Create a StopWatch object
StopWatch timer = new StopWatch();
//create random numbers
randomnumbers numbers = new randomnumbers();
//Create the size of the array
numbers.getSize();
// Invoke the start method in StopWatch class
timer.start();
//sort random numbers
selectionSort();
// Invoke the stop method in StopWatch class
timer.stop();
// Display the execution time
System.out.println("The execution time for sorting 100,000 " +
"numbers using selection sort: " + timer.getElapsedTime() +
" milliseconds");
}
// selectionSort performs a selection sort on an array
public static void selectionSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
int min = array[i];
int minIndex = i;
for (int j = i + 1; j < array.length; j++) {
if (array[j] < min) {
min = array[j];
minIndex = j;
}
}
if (i != minIndex) {
array[minIndex] = array[i];
array[i] = min;
}
}
}
}
Where exactly are you getting "incompatible types random numbers cannot be converted to int" error?
There are multiple issues with the code:
Unconventional naming
size field is in randomnumbers class is used as actual array size in constructor but in createArray it's overshadowed with a parameter of the same name but different type and meaning.
You are not passing any array to selectionSort in Main. This is where I get compile error on your code.
printArray has if (i < 0) condition that is false for all ran1.nextInt() numbers so it will not print anything.
Feeding selectionSort with numbers.createArray(new int[numbers.getSize()]) compiles and ends up sorting the array.

C++ std::map set and get using operator[]

I'm trying to build a 2D sparse matrix class using std::map, which should be called in (for example) the following way:
SparseMatrix<double> M(2,2); // Create a new sparse matrix with 2 rows and 2 columns
M[{1,1}] = 3.1; // Sets element {1,1} to 3.1
The following class can perform these tasks:
template < typename T >
class SparseMatrix
{
std::map< array<int, 2>, T> data;
const array<int, 2> size;
public:
SparseMatrix(const int rows, const int cols)
: size({ rows, cols }) {}
// []-operator to set and get values from matrix
T& operator[](const array< int,2 > indices)
{
// Check if given indices are within the size of the matrix
if(indices[0] >= size[0] || indices[1] >= size[1])
throw invalid_argument("Indices out of bounds");
return data[indices];
}
};
Using this class it is possible to create a new object and set the element, however, the []-operator is also used to get elements, for example:
std::cout << M[{1,1}] << std::endl;
The problem with this is that if this is used to get an element that is not set already, it creates a new part in the map with the given indices and a value of 0, which is undesired for a sparse matrix class, as the map should only contain the non-zero elements.
Is it possible to solve this problem with the []-operator by making a distinction between 'setting' and 'getting'? In case of 'getting' should the operator only return a 0 without adding it to the map.
You can differentiate between reading and writing by using a proxy instead of a T&. Only showing the relevant code:
template <typename T>
class SparseMatrixProxy {
public:
//for reading an element:
operator T() const {
// Check if given indices are within the size of the matrix
if (indices[0] >= matrix.size[0] || indices[1] >= matrix.size[1])
throw std::invalid_argument("Indices out of bounds");
auto map_it = matrix.data.find(indices);
if (map_it == matrix.data.end()) {
return T{};
}
return map_it->second;
}
//for writing an element:
auto operator=(const T &t) {
//optional: when setting a value to 0 erase it from the map
if (t == T{}) {
matrix.data.erase(indices);
} else {
matrix.data[indices] = t;
}
return *this;
}
};
to be used in SparseMatrix like this:
// []-operator to set and get values from matrix
SparseMatrixProxy<T> operator[](const std::array<int, 2> indices) {
return {*this, indices};
}
With usage:
SparseMatrix<double> M(2, 2); // Create a new sparse matrix with 2 rows and 2 columns
M[{{1, 1}}] = 3.1; // Sets element {1,1} to 3.1
std::cout << M[{{1, 1}}] << '\n';
assert(M.mapsize() == 1); //1 element for index {1,1}
std::cout << M[{{0, 0}}] << '\n';
assert(M.mapsize() == 1); //still 1 element because reading doesn't insert an element
M[{{1, 1}}] = 0;
assert(M.mapsize() == 0); //0 elements because we set the only non-0 element to 0
Complete example.
There is std::map::find method. It returns an iterator and if it equals to map.end() then it means that the element is absent in the map.
Yup, it's a pain in the backside. Luckily the clever C++11 bods realised this and gave us a new method: at.
Use the at method (available from the C++11 standard onwards), which does not do any insertion, although you still need a catch handler for a possible std::out_of_range exception.
See http://en.cppreference.com/w/cpp/container/map/at
It's cheaper from performance point of view to implement sparse matrix by creating own mapping, e.g via storing indices.
template<typename T>
class SparseMatrix
{
...
int m, n;
vector<T> values;
vector<int> cols;
vector<int> rows;
}
template<typename T>
T SparseMatrix<T>::get(int row, int col) const
{
this->validateCoordinates(row, col);
int currCol = 0;
for (int pos = rows.at(row - 1) - 1; pos < rows.at(row) - 1; pos++)
{
currCol = cols.at(pos);
if (currCol == col)
return vals.at(pos);
else if (currCol > col)
break;
}
return T();
}
template<typename T>
SparseMatrix<T> & SparseMatrix<T>::set(T val, int row, int col)
{
// Validate coordinates here?
int pos = rows.at(row - 1) - 1;
int currCol = 0;
for (; pos < rows.at(row) - 1; pos++) {
currCol = cols.at(pos);
if (currCol >= col) {
break;
}
}
if (currCol != col) {
if (!(val == T())) {
this->insert(pos, row, col, val);
}
} else if (val == T()) {
this->remove(pos, row);
} else {
vals.at(pos) = val;
}
return *this;
}
template<typename T>
void SparseMatrix<T>::insert(int index, int row, int col, T val)
{
vals.insert(vals.begin() + index, val);
cols.insert(cols.begin() + index, col);
for (int i = row; i <= this->m; i++)
rows.at(i) = rows.at(i) + 1;
}
And so on...

Attempts to call a method in the same class not working (java)

I'm creating a random number generator which then sorts the digits from largest to smallest. Initially it worked but then I changed a few things. As far as I'm aware I undid all the changes (ctrl + z) but now I have errors at the points where i try to call the methods. This is probably a very amateur problem but I haven't found an answer. The error i'm met with is "method in class cannot be applied to given types"
Here's my code:
public class RandomMath {
public static void main(String[] args) {
String bigger = bigger(); /*ERROR HERE*/
System.out.println(bigger);
}
//create method for generating random numbers
public static int generator(int n){
Random randomGen = new Random();
//set max int to 10000 as generator works between 0 and n-1
for(int i=0; i<1; i++){
n = randomGen.nextInt(10000);
// exclude 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0000
if((n==1111 || n==2222 || n==3333 || n ==4444 || n==5555)
||(n==6666 || n==7777 || n==8888 || n==9999 || n==0000)){
i--;
}
}
return n;
}
//create method for denoting the bigger number
public static String bigger(int generated){
generated = generator(); /*ERROR HERE*/
System.out.println(generated);
int[] times = new int[10];
while (generated != 0) {
int val = generated % 10;
times[val]++;
generated /= 10;
}
String bigger = "";
for (int i = 9; i >= 0; i--) {
for (int j = 0; j < times[i]; j++) {
bigger += i;
}
}
return bigger;
}
}
You have not defined a method bigger(), only bigger(int generated). Therefore, you must call your bigger method with an integer parameter.

check palindrome in java code

I'm making a really simple app in java code, but for some reason it doesnt work. its a palindrome checker.
here is the code.
MAIN:
public class main {
public static void main(String[] args) {
Palindroom.palindroomChecker("RACECAR");
}
}
`Palindroom class:
public class Palindroom {
public static void palindroomChecker(String input) {
String omgekeerd = "";
boolean isPalindroom = false;
int length = input.length();
for(int i = 0; i < length; i++ ) {
String hulp = "" + input.charAt(i);
omgekeerd = omgekeerd + hulp;
}
System.out.println(omgekeerd);
System.out.println(input);
if(omgekeerd.equals(input)){
System.out.println("DIT IS EEN PALINDROOM!");
}
else {
System.out.println("HELAAS, DIT IS GEEN PALINDROOM!");
}
}
}`
For some reason the check in the if-statement doesnt go as it has to go. As you can see i checked omgekeerd and input and i also checked earlier the length of omgekeerd to see if there were clear spaces.
Can someone help me out!
thanks in advance
greetings Mauro Palsgraaf
Your logic is flawed. You're reconstructing a new string by appending every char of the input, in the same order, and then check that both strings are equal. So your method always says that the input is a palindrome.
You should construct a new string by appending the chars in the reverse order.
Or you could make it faster by checking that the nth character is the same as the character at the length - 1 - n position, for each n between 0 and length / 2.
You are not actually reversing the string, looks like omgekeerd will be in the same order as input.
Replace for with for(int i = length-1; i >= 0; i--) {
This can be simplified a lot
boolean isPalindrome = new StringBuilder(input).reverse().equals(input);
Maybe this would work for you?
String str = "madam i'm adam."; // String to compare
str = str.replaceAll("[//\\s,',,,.]",""); // Remove special characters
int len = str.length();
boolean isSame = false;
for(int i =0; i<len;i++){
if(str.charAt(i) == str.charAt(len-1-i)){
isSame = true;
}
else{
isSame = false;
break;
}
}
if(isSame){
System.out.print("Equal");
}
else{
System.out.print("Not equal");
}
i=0;
j=str.length()-1; //length of given string
String str; // your input string
while((i<j)||(i!=j)){
if(str.charAt(i)!=str.charAt(j)){
System.out.println("not palindrome");
break;
}
i++;
j--;
}
System.out.print("palindrome");
//this can used for checking without the need of generating and storing a reverse string

Unity3d: Random.Range() Not working the way I intended

I'm spawning objects from a list and so-far i got them to find a parent object that's already live in the scene.The problem is Random.Range() isn't working like I want. I want the listed Objects to spawn to a random parent, instead, they're spawning to the they're parent relative to the order of the list.
Ex. 0,1,2,3,4,5,6,7,8,9 = Bad
Ex. 8,3,1,4,6,3,7,9,5,2 = Good
lol
var theRange = Random.Range(obj1.Length,obj1.Length);
for(var i: int = 0; i < theRange; i++){
var obj2 : GameObject = obj1[i];
if(obj2.transform.childCount == 0){
objfromList.transform.parent = obj2.transform;
objfromList.transform.localPosition = Vector3(0,-2,0);
}
}
Deeply thankful
Following up on my comment, it sounds like you just want a shuffle function. Here is a simple Fisher-Yates shuffle:
void shuffle(int[] a){
for(int i = a.Length-1; i>=0; i--){
int j = Random.Range(0,i);
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
void usage(){
int[] a = {0,1,2,3,4,5}; // assumes obj1.Length = 6
shuffle(a);
for(int i = 0; i < a.Length; i++){
GameObject obj2 = obj1[a[i]];
GameObject objFromList = GetNextObject(); // dummy method grabbing next list object
objFromList.transform.parent = obj2.transform;
objFromList.transform.localPosition = Vector3(0,-2,0);
}
}
This should get you part way to what you need. If the order of obj1 isn't important you can shuffle it directly instead of using a secondary array like a in my example.