3 sty
Laboratoria nr 15 program nr 1
Projektowanie klas i programowanie obiektowe na przykładzie aplikacji do przetwarzanie tekstu.
Poniżej został zaprezentowany szkielet aplikacji do przetwarzania tekstu, który będzie rozbudowywany i omawiany wraz z nowymi laboratoriami. Przedstawiane zagadnienia będą obejmowały zawansowane aspekty programowania w c++. Czytelnicy nabiorą biegłości w wykorzystaniu biblioteki standardowej STL oraz Boost. Zapoznają się z szablonami oraz metodami projektowania klas. Wszytko zostanie przedstawione na podstawie projektowania i implementacji programu do przetwarzania tekstu.
Poniżej zaprezentowano interfejsy jak i ich implementacja klas które będą omawiane, refaktoryzowane i stosowane podczas omawiania ww. materiału. Podstawowy szkielet aplikacji składa się z następujących plików:
– agencyText.cpp – zawiera kod wykonawczy programu oraz testy zaprojektowanych i zaimplementowanych interfejsów,
– textAgent.h oraz textAgent.cpp – interfejs oraz jego implementacja do rejestrowania i użytkowania modułu do przetwarzania tekstu,
– textTool.h oraz textTool.cpp – interfejs oraz jego implementacja do przetwarzania strumienia tekstowego.
Kod aplikacji wykorzystujący utworzone interfejsy przedstawia listing poniżej:
agencyText.cpp //============================================================================ // Name : agencyText.cpp // Author : Marcin Mirończuk // Version : 1.0 // Copyright : GPL // Description : The agency to text retrive //============================================================================ /** * Rejestracja bibliotek */ #include <iostream> #include <string> #include <vector> #include "textAgent.h" /** * Rejestracja przestrzeni nazw */ using namespace std; using namespace ta; /** * Program glowny */ int main() { /** * Wystartowanie kilku agentow dynamicznych oraz statycznych, nazwanych jak i nienazwanych (anonimowych) */ ta::textAgent agentStatyczny(1220, 1, "przetwarzacz tekstu 1", "Agent T1"); ta::textAgent niezweryfikowanyAgentStatyczny; textAgent *agentDynamiczny = new textAgent(12330, 2, "przetwarzacz tekstu 2", "Agnet T2"); textAgent *niezweryfikowanyAgentDynamiczny = new textAgent(); try { /** * Pokazanie informacji o rezydujacych agentach */ cout << "Zarejestrowany agent i jego dane:" << endl; agentStatyczny.showData(); cout << endl; cout << "Agent oczekujacy na rejestracje:" << endl; niezweryfikowanyAgentStatyczny.showData(); cout << endl; cout << "Agent dynamiczny zarejstrowany:" << endl; agentDynamiczny->showData(); cout << endl; cout << "Agent dynamiczny niezweryfikowany:" << endl; niezweryfikowanyAgentDynamiczny->showData(); cout << endl; /** * Rejestracja modulu (przybornika) do przetwarzania tekstow */ tt::textTool tt; /** * Rejestracja przybornika dla agenta dynamicznego */ agentDynamiczny->rejestrTextTool(tt); agentDynamiczny->rejestrTextTool().extractSegments("Ala ma kota."); cout << "Ilosc zliczonych segmentow: " << agentDynamiczny->rejestrTextTool().getCountSegments() << endl; cout << "Pokaz jakie segmenty zliczyles: " << endl; agentDynamiczny->rejestrTextTool().showSegments(); cout << endl; /** * Rejestracja przybornika dla agenta statycznego */ agentStatyczny.rejestrTextTool(tt); agentStatyczny.rejestrTextTool().extractSegments("A ja mam kota. I wiecej tekstu."); cout << "Ilosc zliczonych segmentow: " << agentStatyczny.rejestrTextTool().getCountSegments() << endl; cout << "Pokaz jakie segmenty zliczyles: " << endl; agentStatyczny.rejestrTextTool().showSegments(); cout << endl; cout << "Testowanie usowania spacji:" << endl; std::string testString1 = " kota "; cout << "- Tekst przed filtracja: " << testString1 << endl; cout << "- Filtracja: " << "Tekst odfiltrowany: " << agentStatyczny.rejestrTextTool().stripWhiteSpace(testString1) << endl; cout << "- Filtracja: " << "Tekst pierwotny " << testString1 << endl; std::string *pTestString1 = &testString1; cout << "- Tekst przed filtracja wskaznik / zmienna: " << *pTestString1 << " / " << testString1 << endl; agentStatyczny.rejestrTextTool().stripWhiteSpace(pTestString1); cout << "- Filtracja: " << "Tekst odfiltrowany " << *pTestString1 << endl; cout << "- Filtracja: " << "Tekst pierwotny " << testString1 << endl; cout << endl; cout << "Testowanie tokenizacji:" << endl; std::string testString2 = "Ala ma kota. A kot ma na imie Ala."; cout << "- Tekst podlegajacy tokenizacji: " << testString2 << endl; agentStatyczny.rejestrTextTool().tokenize(testString2); cout << "- Ilosc tokenow: " << agentStatyczny.rejestrTextTool().getCountTokens() << endl; cout << "- Ilosc unikatowych tokenow: " << agentStatyczny.rejestrTextTool().getCountUniqueTokens(); delete niezweryfikowanyAgentDynamiczny; delete agentDynamiczny; } catch (std::string exception) { cout<<"Wyjatek: "<< exception; delete niezweryfikowanyAgentDynamiczny; delete agentDynamiczny; } return 0; }
Interfejs agenta który rejestruje moduł do przetwarzania tekstu i za pośrednictwem którego odbywają się wszelkie modyfikacja przedstawia listing poniżej:
/* * textAgent.h * * Created on: 21-12-2011 * Author: Marcin Mirończuk * Licenc: GPL * * Klas modelujaca podstawowe elementy agenta do przetwarzania tekstu. * Agent ma mozliwosc rejestrowania u siebie modulu do przetwarzania tekstu za omoca ktorego przetwarza tekst. * */ #include <string> #include "textTool.h" #ifndef TA_H_ #define TA_H_ /** * Definicja przestrzeni nazw */ namespace ta { /** * Definicja klasy */ class textAgent { /** * Skladowe i metody prywatne klasy */ private: /** * @type int timeCreate Czas w sekundach Unix timestamp */ int timeCreate; /** * @type float priority Priorytet agebta */ int priority; /** * @type string task Zadanie/praca do wykonania przez agebta */ std::string task; /** * @type string name Nazwa agenta */ std::string name; /** * @type bool isTextTool Flaga rejestracji modulu tekstu */ bool isTextTool; /** * @type textTool textTool Uchwyt do modulu przetwarzajacego tekst */ tt::textTool textTool; /** * Skladowe i metody publiczne klasy */ public: /** * Konstruktor podstawowy domyslny */ textAgent(); /** * Konstruktor rozszerzony */ textAgent(float ptimeCreate, float ppriority, std::string ptask, std::string pname); /** * Pobranie wieku agenta * * @return float */ int getTimeCreate(); /** * Pobranie wagi agenta * * @return float */ int getPriority(); /** * Pobranie zadania agenta * * @return string */ std::string getTask(); /* * Pobranie nazwy agenta * * @return string */ std::string getName(); /** * Pokazanie danych o agencie * * @return void */ void showData(); /** * Rejestracja modulu do przetwarzania tekstu * * @return tt::textTool */ const tt::textTool & rejestrTextTool(tt::textTool tt); /** * Rejestracja, pobranie modulu do przetwarzania tekstu * * @return tt::textTool * @thorw exception */ tt::textTool & rejestrTextTool(); /** * Destruktor */ virtual ~textAgent(); }; } /* namespace textagent */ #endif /* TA_H_ */
Interfejs programu (modułu) do przetwarzania strumienia danych tekstowych przedstawia listing poniżej:
/* * textAgent.cpp * * Created on: 21-12-2011 * Author: Marcin Mirończuk * Licenc: GPL * * Implementacja interfejsu agenta do przetwarzania tekstu @see textAgent.h * */ #include <iostream> #include "textAgent.h" #include "textTool.h" namespace ta { textAgent::textAgent() { this->timeCreate = 0; this->priority = 0; this->task = "unknown"; this->name = "inkognito"; this->isTextTool = false; } textAgent::textAgent(float ptimeCreate, float ppriority, std::string ptask, std::string pname) { this->timeCreate = ptimeCreate; this->priority = ppriority; this->task = ptask; this->name = pname; this->isTextTool = false; } int textAgent::getTimeCreate() { return this->timeCreate; } int textAgent::getPriority() { return this->priority; } std::string textAgent::getTask() { return this->task; } std::string textAgent::getName() { return this->name; } void textAgent::showData() { std::cout << "Time create: " << this->timeCreate << std::endl; std::cout << "Priority: " << this->priority << std::endl; std::cout << "Name: " << this->name << std::endl; std::cout << "Task: " << this->task << std::endl; } const tt::textTool & textAgent::rejestrTextTool(tt::textTool tt) { if(this->isTextTool == false) { this->textTool = tt; this->isTextTool = true; return this->textTool; } else { return this->textTool; } } tt::textTool & textAgent::rejestrTextTool() { if(this->isTextTool == false) { std::string exception = "Unregister text tool!"; throw exception; } else { return this->textTool; } } textAgent::~textAgent() { } } /* namespace ta */
Implementację interfejsu programu do przetwarzania tekstu zawiera listing poniżej:
/* * textTool.h * * Created on: 21-12-2011 * Author: Marcin Mirończuk * Licenc: GPL * * Klas modelujaca modul (przybornik) do przetwarzania tekstu. * */ #include <map> #include <vector> #include <string> #ifndef TT_H_ #define TT_H_ /** * Definicja przestrzeni nazw */ namespace tt { /** * Definicja klasy */ class textTool { /** * Skladowe i metody prywatne klasy */ private: /** * @type vector<string> segment Wektor segmentow */ std::vector<std::string> segments; /** * @type vector<string> tokens Wektor tokenow (wyrazen) */ std::vector<std::string> tokens; /** * @type vector<string> uniqueTokens Wektor unikalnych tokenow (wyrazen) */ std::vector<std::string> uniqueTokens; /** * @type vector<string, int> tokensFrequ Tablica klucz=wartosc czestotliwosci wyrazen */ std::map<std::string, int> tokensFrequ; /** * Usowanie duplikatow wyrazen z wektora wyrazen * * @see http://learningcppisfun.blogspot.com/2008/04/remove-duplicates-from-vector.html * @see http://stackoverflow.com/questions/1041620/most-efficient-way-to-erase-duplicates-and-sort-a-c-vector * * @param vector<string> vec * * @return vector<string> */ std::vector<std::string> removeDuplicates(std::vector<std::string> vec); public: /** * Domyslny konstruktor */ textTool(); /** * Wydobywanie segmentow z tekstu. * * @param string &text * * @return vector<string> */ std::vector<std::string> extractSegments(const std::string &text); /** * Pobranie ilosci wydobytych segmentow z tekstu. * * @return int */ int getCountSegments(); /** * Pokazanie wydobytych segmentow z tekstu. * * @return void */ void showSegments(); /** * Usuniecie spacji z poczatku jak i z konca lancucha znakow. * * @param string text * * @return string */ std::string stripWhiteSpace(std::string text); /** * Przeciazona wersja usuniecia spacji z poczatku jak i z konca lancucha znakow. * * @param string *text * * @return void */ void stripWhiteSpace(std::string *text); /** * Kalkulacja, wyznaczanie macierzy czetotliwosci wystepowania wyrazen w pojedynczym dokumencie tekstowym. * * @param string &text * * @return map<string, int> */ std::map<std::string, int> computeTokensFrequ(const std::string &text); /** * Tokenizacja tekstu tj. rozbicie tekstu na wektor wyrazen. * @see http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html * * @param string &text * * @return vector<string> */ std::vector<std::string> tokenize(const std::string &text); /** * Pobranie ilosci wyrazen. * * @return int */ int textTool::getCountTokens(); /** * Pobranie ilosci unikalnych wyrazen. * * @return int */ int textTool::getCountUniqueTokens(); /** * Domyslny destruktor */ virtual ~textTool(); }; } /* namespace tt */ #endif /* TT_H_ */
Implementację powyżej zaprezentowanego interfejsu programu do przetwarzania tekstu zawiera listing poniżej:
/* * textTool.cpp * * Created on: 21-12-2011 * Author: Marcin Mirończuk * Licenc: GPL * * Implementacja interfejsu modulu do przetwarzania tekstu @see textTool.h * */ #include <iostream> #include <vector> #include <string> #include <sstream> #include <algorithm> #include "textTool.h" namespace tt { textTool::textTool() { } /** * Bardzo naiwna, prezentacyja wersji algorytmu do rozbijania tekstu na segmenty (zdania) */ std::vector<std::string> textTool::extractSegments(const std::string &text) { std::string tempSegment; for(int i = 0; i < text.length(); i++) { if(text[i] == '.' || text[i] == '?' || text[i] == '!') { tempSegment = (std::string) tempSegment; this->segments.push_back(this->stripWhiteSpace(tempSegment)); tempSegment.clear(); } else { tempSegment += text[i]; } } return this->segments; } int textTool::getCountSegments() { return this->segments.size(); } std::string textTool::stripWhiteSpace(std::string text) { if(text[0] == ' ') { text.replace(0, 1, ""); } if(text[text.length()-1] == ' ') { text.replace(text.length()-1, 1, ""); } return text; } void textTool::stripWhiteSpace(std::string *text) { std::string::iterator it; it = text->begin(); if(*it == ' ') { text->replace(0, 1, ""); } it = text->end(); if(*(it-1) == ' ') { text->replace(text->length()-1, 1, ""); } } void textTool::showSegments() { for(int i = 0; i < this->segments.size(); i++) { std::cout << this->segments[i] << std::endl; } } std::map<std::string, int> textTool::computeTokensFrequ(const std::string &text) { this->tokenize(text); this->removeDuplicates(this->tokens); std::vector<std::string>::iterator it; for (it = this->uniqueTokens.begin(); it < this->uniqueTokens.end(); it++) { std::cout << " " << *it; } return this->tokensFrequ; } std::vector<std::string> textTool::tokenize(const std::string &text) { // Buforowany string std::string buf; // Wstawienie stringu z potoku std::stringstream ss(text); while (ss >> buf) { this->tokens.push_back(buf); } return this->tokens; } int textTool::getCountTokens() { return this->tokens.size(); } int textTool::getCountUniqueTokens() { if(this->tokens.size() != 0 && this->uniqueTokens.size() == 0) { this->removeDuplicates(this->tokens); return this->uniqueTokens.size(); } else { return this->uniqueTokens.size(); } } std::vector<std::string> textTool::removeDuplicates(std::vector<std::string> vec) { std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); this->uniqueTokens = vec; return this->uniqueTokens; } textTool::~textTool() { } } /* namespace tt */
Skomentuj ten wpis