Problem p02269 (C++) — buggy submission, verdict: Time Limit Exceeded

//	-*- mode: C++ -*-
//	Search III
//		Your task is to write a program of a simple dictionary which
//implements the following instructions:
//
//		insert str: insert a string str in to the dictionary
//		find str: if the distionary contains str, then print 'yes',
//otherwise print 'no' 	Input 		In the first line n, the number of instructions is
//given. In the following n lines, n instructions are given in the above
//mentioned format.
//
//	Output
//		Print yes or no for each find instruction in a line.
//
//	Constraints
//		A string consists of 'A', 'C', 'G', or 'T'
//		1 ≤ length of a string ≤ 12
//		n ≤ 1000000
//	Sample Input 1
//		5
//		insert A
//		insert T
//		insert C
//		find G
//		find A
//	Sample Output 1
//		no
//		yes
//	Sample Input 2
//		13
//		insert AAA
//		insert AAC
//		insert AGA
//		insert AGG
//		insert TTT
//		find AAA
//		find CCC
//		find CCC
//		insert CCC
//		find CCC
//		insert T
//		find TTT
//		find T
//	Sample Output 2
//		yes
//		no
//		no
//		yes
//		yes
//		yes

#include <iostream>
#include <string>
#include <vector>

struct HashList {
  std::string keyWord;
  HashList *Next;

  HashList();
};

HashList::HashList() : Next(nullptr) {}

class HashTable {
private:
  static const unsigned int hashSize = 1024 * 1024;
  const unsigned int maxKeySize = 12;
  HashList *hashList[hashSize]{nullptr};
  std::vector<std::string> result;

  unsigned int getChar(const char ch);
  unsigned int getKey(const std::string str);

public:
  HashTable();
  ~HashTable();

  void insert(const std::string str);
  void find(const std::string str);
  void print(void);
};

unsigned int HashTable::getChar(const char ch) {
  if (ch == 'A') {
    return 1;
  } else if (ch == 'C') {
    return 2;
  } else if (ch == 'G') {
    return 3;
  } else {
    return 4;
  }
}

unsigned int HashTable::getKey(const std::string str) {
  unsigned long long sum{0};
  unsigned long long p{1};

  for (unsigned int i = 0; i < str.length(); i++) {
    sum += p * (getChar(str[i]));
    p *= 5;
  }

  return static_cast<unsigned int>(sum % hashSize);
}

HashTable::HashTable() {}

HashTable::~HashTable() {}

void HashTable::insert(const std::string str) {
  unsigned int key = getKey(str);
  HashList **pp = &hashList[key];
  HashList *p = hashList[key];

  //	std::cout << "insert " << str << " key = " << key << '\\n';
  while (p != nullptr) {
    //		std::cout << "insert p = " << p << " p->keyWord = " << p->keyWord <<
    //'\\n';
    if (p->keyWord == str) {
      return;
    }
    pp = &(p->Next);
    p = p->Next;
  }

  //	std::cout << "insert p = " << p << '\\n';
  *pp = new HashList;
  p = *pp;
  p->keyWord = str;
  //	std::cout << "insert p = " << p << " p->keyWord = " << p->keyWord <<
  //'\\n';
}

void HashTable::find(const std::string str) {
  unsigned int key = getKey(str);
  HashList *p = hashList[key];

  //	std::cout << "find " << str << " key = " << key << '\\n';
  while (p != nullptr) {
    //		std::cout << "find p = " << p << " p->keyWord = " << p->keyWord <<
    //'\\n';
    if (p->keyWord == str) {
      result.push_back("yes");
      //			std::cout << "yes" << str << ' ' << key << '\\n';
      return;
    }

    p = p->Next;
  }

  result.push_back("no");
  //	result.push_back("no" + str);
  //	std::cout << "no " << str << ' ' << key << '\\n';
}

void HashTable::print(void) {
  for (auto res : result) {
    std::cout << res << '\\n';
  }
}

HashTable h;

int main(int argc, char *argv[]) {
  unsigned int count{0};

  std::cin >> count;

  for (auto i = 0; i < count; i++) {
    std::string command{};
    std::string str{};

    std::cin >> command >> str;

    if (command[0] == 'i') {
      h.insert(str);
    } else {
      h.find(str);
    }
  }

  h.print();

  return 0;
}


Error: TLE

Fixed submission:

//	-*- mode: C++ -*-
//	Search III
//		Your task is to write a program of a simple dictionary which
//implements the following instructions:
//
//		insert str: insert a string str in to the dictionary
//		find str: if the distionary contains str, then print 'yes',
//otherwise print 'no' 	Input 		In the first line n, the number of instructions is
//given. In the following n lines, n instructions are given in the above
//mentioned format.
//
//	Output
//		Print yes or no for each find instruction in a line.
//
//	Constraints
//		A string consists of 'A', 'C', 'G', or 'T'
//		1 ≤ length of a string ≤ 12
//		n ≤ 1000000
//	Sample Input 1
//		5
//		insert A
//		insert T
//		insert C
//		find G
//		find A
//	Sample Output 1
//		no
//		yes
//	Sample Input 2
//		13
//		insert AAA
//		insert AAC
//		insert AGA
//		insert AGG
//		insert TTT
//		find AAA
//		find CCC
//		find CCC
//		insert CCC
//		find CCC
//		insert T
//		find TTT
//		find T
//	Sample Output 2
//		yes
//		no
//		no
//		yes
//		yes
//		yes

#include <iostream>
#include <string>
#include <vector>

struct HashList {
  std::string keyWord;
  HashList *Next;

  HashList();
};

HashList::HashList() : Next(nullptr) {}

class HashTable {
private:
  static const unsigned int hashSize = 2 ^ 20;
  const unsigned int maxKeySize = 12;
  HashList hashList[hashSize]{};
  std::vector<std::string> result;

  unsigned int getChar(const char ch);
  unsigned int getKey(const std::string str);

public:
  HashTable();
  ~HashTable();

  void insert(const std::string str);
  void find(const std::string str);
  void print(void);
};

unsigned int HashTable::getChar(const char ch) {
  if (ch == 'A') {
    return 1;
  } else if (ch == 'C') {
    return 2;
  } else if (ch == 'G') {
    return 3;
  } else {
    return 4;
  }
}

unsigned int HashTable::getKey(const std::string str) {
  unsigned long long sum{0};
  unsigned long long p{1};

  for (unsigned int i = 0; i < str.length(); i++) {
    sum += p * (getChar(str[i]));
    p *= 5;
  }

  return sum % hashSize;
}

HashTable::HashTable() {}

HashTable::~HashTable() {}

void HashTable::insert(const std::string str) {
  unsigned int key = getKey(str);

  if (hashList[key].keyWord.empty()) {
    hashList[key].keyWord = str;
    return;
  }

  HashList **p = &(hashList[key].Next);

  while (*p != nullptr) {
    *p = (*p)->Next;
  }

  *p = new HashList;
  (*p)->keyWord = str;
}

void HashTable::find(const std::string str) {
  unsigned int key = getKey(str);

  if (hashList[key].keyWord == str) {
    result.push_back("yes");
    return;
  }

  HashList **p = &hashList[key].Next;

  while (*p != nullptr) {
    if ((*p)->keyWord == str) {
      result.push_back("yes");
      return;
    }
  }

  result.push_back("no");
}

void HashTable::print(void) {
  for (auto res : result) {
    std::cout << res << '\\n';
  }
}

HashTable h;

int main(int argc, char *argv[]) {
  unsigned int count{0};

  std::cin >> count;

  for (auto i = 0; i < count; i++) {
    std::string command{};
    std::string str{};

    std::cin >> command >> str;

    if (command[0] == 'i') {
      h.insert(str);
    } else {
      h.find(str);
    }
  }

  h.print();

  return 0;
}