0

I wanted to create a hash table that contains strings separated by their initial characters. There are 26 vectors in my hash table for 26 letters.

#ifndef _MYHASHTABLE_H_
#define _MYHASHTABLE_H_

#include <string>
#include <vector>

class myHashTable {
private:
    int n;
    std::vector<int> intMyVector[26];
    std::vector<std::string> strMyVector[26];

public:
    int hashFunction(std::string str);
    void pushBack(std::string str, int i);
    void display();
};

#endif

#include "myHashTable.h"
#include <iostream>
#include <string>

int myHashTable::hashFunction(std::string str) {
    if (*str.begin() <= 122 && *str.begin() >= 97)
        return (*str.begin() % 26) - 19;
    else if (*str.begin() <= 90 && *str.begin() >= 65)
        return (*str.begin() % 26) - 13;
}

void myHashTable::pushBack(std::string str, int i) {
    strMyVector[hashFunction(str)].push_back(str);
    intMyVector[hashFunction(str)].push_back(i);
}

void myHashTable::display() {
    for (int i{}; i < 26; i++) {
        for (int j{}; j < (strMyVector[i].size()); j++)
            std::cout << strMyVector[i][j] << " " << intMyVector[i][j] << std::endl;
    }
}

First I give 3 inputs with "a", "b", "c" initials. There was not any error. But whenever I break the alphabetical order it crashes and it doesn't even display the first 3 outputs. How do I fix this problem?

#include <iostream>
#include <string>
#include <vector>
#include "myHashTable.h"

int main() {
    myHashTable hash;

    hash.pushBack("abcd", 1);
    hash.pushBack("bcd", 2);
    hash.pushBack("cda", 4);
    hash.pushBack("zaxs", 1);

    hash.display();

    return 0;
}
Chris
  • 9,043
  • 4
  • 12
  • 31
  • 1
    Don't use magic numbers, like `97`. Use `'a'` so it's easier to see what you mean. – Ted Lyngmo Jan 24 '22 at 18:13
  • 1
    Also [be careful with underscores](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). You won't often run into a problem with an identifier like `_MYHASHTABLE_H_`, but when you do, it hits hard. – user4581301 Jan 24 '22 at 18:16
  • 1
    You are using modular arithmetic on _alphabet characters_. It doesn’t work that way. Convert to a digit range first. For example, 'A'–'Z' can be converted to 0–25 with `int value = capital_letter - 'A'` – Dúthomhas Jan 24 '22 at 18:18
  • 2
    `hashFunction` doesn't always return a value it seems. – Ted Lyngmo Jan 24 '22 at 18:19
  • 1
    The `if`/`else if` in `hashFunction` needs a bit of work. – user4581301 Jan 24 '22 at 18:20
  • 1
    The result of `anything % 26` is number between `0` and `25`. If you subtract `19` from that, you can get values from `-19` to `6`. You then use the number (which is in range `-19` to `6`) as array index. See the problem? – Yksisarvinen Jan 24 '22 at 18:20
  • The programmer's secret weapon is the debugger. With a debugger you can run the program at your speed and watch what the program does as it does it. As soon as you see the program do something you didn't expect like take the wrong path or store the wrong value, stop. The unexpected is either a bad assumption or a bug in the code. Either one needs fixing. – user4581301 Jan 24 '22 at 18:24
  • Btw, what is the purpose of `-19` and `-13`? If you'd given those numbers descriptive names I would probably not have to ask. – Ted Lyngmo Jan 24 '22 at 18:29
  • Rather than manually checking if a character is upper or lower case, you may want to use [`std::islower`](https://en.cppreference.com/w/cpp/string/byte/islower) and [`std::isupper`](https://en.cppreference.com/w/cpp/string/byte/isupper). – Chris Jan 24 '22 at 18:29
  • @TedLyngmo `97 % 26 == 19`, `65 % 26 == 13`, OP seems to have wanted to put strings starting with `a` in the first index in the table. – Yksisarvinen Jan 24 '22 at 18:33
  • @Yksisarvinen Ah, yes. I wonder if simply doing `unsigned myHashTable::hashFunction(const std::string_view& str) { return str.front() % number_of_letters; }` would be a better option. – Ted Lyngmo Jan 24 '22 at 18:39

0 Answers0