Pagini recente » Cod sursa (job #2577803) | Cod sursa (job #3038923) | Cod sursa (job #114015) | Cod sursa (job #1781988) | Cod sursa (job #1560516)
#include <fstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <cstdio>
using InstructionWordPair = std::tuple<char, std::string>;
struct TrieNode
{
TrieNode()
{
for (int i = 0; i < 26; ++i)
{
Children[i] = nullptr;
}
}
int OccurrenceCount = 0;
int ChildCount = 0;
TrieNode* Children[26];
};
TrieNode* root = new TrieNode();
InstructionWordPair LineToInstructionAndWord(const std::string& line)
{
char instruction = line[0];
std::string word = line.substr(2);
return std::make_tuple(instruction, word);
}
namespace detail
{
int CharToChildIndex(char c)
{
return c - 'a';
}
bool Delete(TrieNode* node, const std::string& word, int indexInWord)
{
if (indexInWord == word.length())
{
node->OccurrenceCount--;
}
else
{
int childIndex = CharToChildIndex(word[indexInWord]);
if (Delete(node->Children[childIndex], word, indexInWord + 1))
{
delete node->Children[childIndex];
node->Children[childIndex] = nullptr;
node->ChildCount--;
}
}
return node->OccurrenceCount <= 0 && node->ChildCount <= 0;
}
int CountLongestCommonPrefix(const TrieNode* node, const std::string& word, int indexInWord, int lengthSoFar)
{
if (indexInWord == word.length())
{
return lengthSoFar;
}
int childIndex = CharToChildIndex(word[indexInWord]);
if (node->Children[childIndex] != nullptr)
{
return CountLongestCommonPrefix(node->Children[childIndex], word, indexInWord + 1, lengthSoFar + 1);
}
return lengthSoFar;
}
void AddWordOccurrence(TrieNode* node, const std::string& word, int indexInWord)
{
if (indexInWord == word.length())
{
node->OccurrenceCount++;
}
else
{
int childIndex = CharToChildIndex(word[indexInWord]);
if (node->Children[childIndex] == nullptr)
{
auto newNode = new TrieNode();
node->Children[childIndex] = newNode;
node->ChildCount++;
AddWordOccurrence(newNode, word, indexInWord + 1);
}
else
{
AddWordOccurrence(node->Children[childIndex], word, indexInWord + 1);
}
}
}
int CountOccurrences(TrieNode* node, const std::string& word, int indexInWord)
{
if (indexInWord == word.length())
{
return node->OccurrenceCount;
}
int childIndex = CharToChildIndex(word[indexInWord]);
if (node->Children[childIndex] != nullptr)
{
return CountOccurrences(node->Children[childIndex], word, indexInWord + 1);
}
return 0;
}
}
void AddWordOccurrence(const std::string& word)
{
detail::AddWordOccurrence(root, word, 0);
}
void DeleteWordOccurrence(const std::string& word)
{
detail::Delete(root, word, 0);
}
int CountOccurrences(const std::string& word)
{
return detail::CountOccurrences(root, word, 0);
}
int CountLongestCommonPrefix(const std::string& word)
{
return detail::CountLongestCommonPrefix(root, word, 0, 0);
}
void Execute(const InstructionWordPair& instructionAndWord)
{
const char instruction = std::get<0>(instructionAndWord);
const std::string word = std::get<1>(instructionAndWord);
switch (instruction)
{
case('0') :
AddWordOccurrence(word);
break;
case('1') :
DeleteWordOccurrence(word);
break;
case('2') :
printf("%d\n", CountOccurrences(word));
break;
case('3') :
printf("%d\n", CountLongestCommonPrefix(word));
break;
default:
break;
}
}
int main()
{
char line[32];
freopen("trie.in", "r", stdin);
freopen("trie.out", "w", stdout);
fgets(line, 32, stdin);
while (!feof(stdin))
{
char instruction = line[0];
int lineLen = 0;
do
{
lineLen++;
} while (line[lineLen] != '\n');
std::string word(line + 2, line + lineLen);
Execute(std::make_tuple(instruction, word));
fgets(line, 32, stdin);
}
}