Cod sursa(job #2746785)

Utilizator IoanaNadIoana Nadia Puiu IoanaNad Data 28 aprilie 2021 14:58:50
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.41 kb
#include <fstream>
#include <string>
#include <vector>
using namespace std;

struct Node {
	string letter;
	int endings;
	int nrAppear;
	vector<Node*> children;
};

class Trie {
public:
	Trie() {
		Node* temp = new Node;
		temp->letter = "";
		temp->endings = 0;
		temp->nrAppear = 0;
		root = temp;
	}

	Node* findNewPosition(Node* auxAddress, string word, int position) {
		int length = auxAddress->children.size();
		for (int j = 0; j < length; ++j)
			if (auxAddress->children[j]->letter[0] == word[position])
				return auxAddress->children[j];
		return auxAddress;
	}

	void addNewWord(string word) {
		int wordLength = word.length();
		Node* auxAddress = root;
		for (int i = 0; i < wordLength; ++i) {
			Node* secondAddress = findNewPosition(auxAddress, word, i);
			if (auxAddress == secondAddress) {
				Node* newNode = new Node;
				string letter = "";
				letter += word[i];
				newNode->letter = letter;
				newNode->nrAppear = 1;
				if (i == wordLength - 1)
					newNode->endings = 1;
				else
					newNode->endings = 0;
				auxAddress->children.push_back(newNode);
				auxAddress = newNode;
			}
			else {
				if (i == wordLength - 1)
					secondAddress->endings++;
				secondAddress->nrAppear++;
				auxAddress = secondAddress;
			}
		}
	}

	int position(vector<Node*> elements, Node* node) {
		int length = elements.size();
		for (int i = 0; i < length; ++i) {
			if (elements[i] == node)
				return i;
		}
		return -1;
	}

	void deleteAppearWord(string word) {
		int length = word.length();
		vector<Node*>  lettersAddresses;
		Node* address = root;
		for (int i = 0; i < length; ++i) {
			Node* secondAddress = findNewPosition(address, word, i);
			if (secondAddress->nrAppear == 1) {
				int pos = position(address->children, secondAddress);
				address->children.erase(address->children.begin() + pos);
				lettersAddresses.push_back(secondAddress);
			}
			else {
				secondAddress->nrAppear--;
				if (i == length - 1)
					secondAddress->endings--;
			}
			address = secondAddress;
		}
		int addressesNumber = lettersAddresses.size();
		for (int i = 0; i < addressesNumber; ++i)
			if (lettersAddresses[i]->nrAppear == 0)
				delete lettersAddresses[i];
	}

	int appearancesNumber(string word) {
		int wordLength = word.length();
		Node* address = root;
		for (int i = 0; i < wordLength; ++i) {
			Node* secondAddress = findNewPosition(address, word, i);
			if (address == secondAddress)
				return 0;
			address = secondAddress;
		}
		return address->endings;
	}

	int longestPrefix(string word) {
		int length = word.length(), prefixLength = 0;
		Node* address = root;
		for (int i = 0; i < length; ++i) {
			Node* secondAddress = findNewPosition(address, word, i);
			if (address == secondAddress)
				return prefixLength;
			address = secondAddress;
			++prefixLength;
		}
		return prefixLength;
	}

private:
	Node* root;
};

int main() {
	ifstream fin("trie.in");
	ofstream fout("trie.out");
	Trie trie;	
	while (!fin.eof()) {
		string operation, word;
		fin >> operation >> word;
		fin.get();
		int valueOperation = operation[0] - '0';
		switch (valueOperation) {
		case 0:
			trie.addNewWord(word);
			break;
		case 1:
			trie.deleteAppearWord(word);
			break;
		case 2:
			fout << trie.appearancesNumber(word) << "\n";
			break;
		case 3:
			fout << trie.longestPrefix(word) << "\n";
			break;
		}
	}
	return 0;
}