Dziś jest sobota, 10 stycznia 2009 roku (z kalendarza...)

Zmagania z STL-em

Biblioteki STL z C++ zacząłem uczyć się przed drugim etapem OI, głównie w celu przyspieszenia wykonywania zadań na tejże. Pracuje się z nią fajnie, ale tylko do momentu, gdy nie kończy nam się pomysłowość na wprowadzenie w życie nieco bardziej niecnych zamiarów. Mnogość szablonów, interakcji między klasami jest na tyle duża, że trzeba mieć cały czas głowę na karku i rozważnie wszystko planować, a i tak czasem okazuje się, że szybciej da się napisać własną implementację, niż debugować STL-owy kod :).

Oto jedna z takich sytuacji. Jutro robimy w szkole pierwsze z serii spotkań zorientowanych bezpośrednio pod kątem matury z informatyki (jest nas w liceum całe pięć osób :)), więc postanowiłem, że podzielę się z resztą własną wiedzą i doświadczeniem, przy okazji samemu sobie utrwalając wszystko. Na pierwszy ogień poszło zadanie "Słowa" z poprzedniej matury, a konkretnej jeden z podpunktów, gdzie należało wczytać do pamięci listę słów i określić, ile z nich się powtarza. Nie jest to skomplikowane do wykonania, a biorąc pod uwagę fakt, że podczas egzaminu plik z danymi liczył tylko 1000 słów, było wręcz trywialne, bowiem nawet najgłupszy, acz poprawny algorytm, dawał odpowiedź niemal błyskawicznie. Najgłupszy mnie nie zadowalał, więc zwiększyłem rozmiar pliku 100 razy i zakodowałem jeszcze dwa inne sposoby obliczenia wyniku. W każdym z nich używany był STL.

Najdłużej zeszło mi z algorytmem wykorzystującym tablice haszujące do wyszukiwania elementów. Na warsztat poszła klasa hash_map z STL-a, będąca wprawdzie nieoficjalnym rozszerzeniem firmy SGI, ale szerokodostępnym. Napisawszy kod, przystępuję do próby jego kompilacji i powstaje problem, ponieważ g++ zgłasza po kilkanaście komunikatów błędów, na pół ekranu każdy. Odnalezienie czegokolwiek sensownego w tym gąszczu znaczków oraz identyfikatorów graniczyło z cudem. Stopniowo wydobywałem z tej masy numery linii i z pomocą bożą usuwałem kolejne usterki (a to niekompatybilność typów, a to brak jakiegoś parametru...). Zniknął wreszcie ostatni błąd składni, puszczam kompilację i... zgłasza się linker, tym razem nie pasuje mu coś znowu w nagłówkach hash_table. Rzecz jasna trafił mnie szlag (jakby mało było tych trzech dotychczasowych kwadransów). Okazało się, że znacznie szybciej zeszło mi z napisaniem własnej, mocno uproszczonej, ale działającej, jak trzeba, tablicy haszującej opartej o prosty std::vector.

class zyxHash
{
	public:
		zyxHash(long int buckets)
		{
			bucketNum = buckets;
			
			bucketList = new vector<slowo*>[bucketNum];
		} // end zyxHash();
 
		// zwalniania pamieci nie chcialo mi sie pisac
		// do tego zadania nie bylo to potrzebne
		
		void insert(string key, slowo *s)
		{
			unsigned long int hash = hashFunc(key);
			bucketList[hash].push_back(s);
		} // end insert();
		
		slowo *find(string key)
		{
			unsigned long int hash = hashFunc(key);
			vector<slowo*> *bt = &bucketList[hash];
			for(long int i = 0; i < bt -> size(); i++)
			{
				if(key == (*bt)[i]->word)
				{
					return (*bt)[i];
				}			
			}
			return 0;
		} // end find();
	private:
		long int hashFunc(string k)
		{
			unsigned long int hash = 0;
			long int i;
			long int key_len = k.length();
			
			for (i = 0; i < key_len; i++) {
				hash += k[i];
				hash += (hash << 10);
				hash ^= (hash >> 6);
			}
			hash += (hash << 3);
			hash ^= (hash >> 11);
			hash += (hash << 15);
 
			return hash % bucketNum;
		} // end hashFunc();
		
		long int bucketNum;
		
		vector<slowo*> *bucketList;
};

Po niecałych 10 minutach program był gotowy.

Z STL-a korzystam też w moim innym projekcie, pisanej z użyciem Turbo Vision aplikacji userist do zarządzania kontami użytkowników na serwerze wraz z ich katalogowaniem. Tam też miałem z nim nieco przebojów, lecz innej natury, mianowicie przekazywania zbiorów między poszczególnymi elementami interfejsu. Jednak mimo tych problemów bibliotekę oceniam dość pozytywnie. Nie trzeba się bawić ze strukturami danych, wszystko jest pod ręką. Jedyna wada jest taka, że gdy ktoś dopiero poznaje tajniki jej działania, czasami poziom złożoności API może człowieka zwyczajnie przerosnąć. Zastanawiam się, jak sprawdziłby się STL w interpreterze Revomera, gdzie mamy do czynienia z nietypową listą instrukcji. W sumie gdy zaczynaliśmy go pisać na warsztatach, jeden z uczestników też pukał się w czoło: po co własne struktury piszecie, skoro STL-a macie. Ale to temat na inną opowieść.

Powrót

Komentarze

Napisał Wielkie G w czwartek, 22 marca 2007 o 16:59

Cóż, STL nie jest wcale taki trudny, lecz właśnie te komunikaty o błędach... Wzorce potrafią czasami nieźle utrudnić życie, ale chyba da sie nimi zrobić praktycznie wszystko, dodatkowo z optymalną prędkością działania w kodzie generycznym. STL-a trzeba się chyba uczyć jako oddzielny język programowania ;)

Strona 1 z 1 :: 1

Skomentuj

NickInformacja
E-mailTylko do użytku wewnętrznego.
WWWNie zapomnij o http://
LayoutNapisz tu, czy widzisz dzienny czy nocny layout.
WpisFormatowanie wiki
Internauto, pamiętaj! Wolność to nie samowola - dbaj o kulturę wypowiedzi oraz dyskusji w sieci.

Na Zyxist.com panuje swoboda wyrażania opinii oraz krytyki pod dowolnym adresem. Jedyny warunek: musi być ona kulturalna i rzeczowa. Na chamstwo, prostactwo lub jawne obrażanie kogokolwiek nie ma tu miejsca i takie komentarze są bardzo szybko usuwane. Jeśli zamierzasz polemizować z treścią wpisu, wpierw uważnie ją przeczytaj.

© Tomasz "Zyx" Jędrzejewski 2005 - 2009 | Wykonanych zapytań: 2 | Serwer wirtualny zapewnia