// Baslangic: 1 Subat 2002 // Yazan: Ali Cehreli // // Programin dogrulugu hakkinda hicbir garantide bulunmuyorum. :) // Deneyip calistigini dogrulayin. // // Bu program girisine verilen sozcuklerin // bir histogramini cikisina verir. #ifdef _MSC_VER // MSVC++'in gereksiz bir uyarisini susturmak icin #pragma warning (disable: 4786) #endif #include #include #include #include using namespace std; // Okumayi kolaylastirmak icin yeni adlar olusturalim typedef map Dagilim; typedef vector Sozcukler; // Sozcukleri normal cikisa gonderen bir fonksiyon void yazdir(Dagilim const & dagilim, ostream & cikis) { // Simdilik 'iterator'u 'yuruyucu' olarak // kullaniyorum. Daha sonra daha iyi oturan // bir sozcuk buluruz. typedef Dagilim::const_iterator Yuruyucu; Yuruyucu const son = dagilim.end(); for (Yuruyucu y = dagilim.begin(); y != son; ++y) { string const & sozcuk = y->first; int const toplam = y->second; cikis << sozcuk << ' ' << toplam << '\n'; } } // string::value_type'in 'char' turunde oldugunu // bildigimiz halde ukalalik olsun diye yine de // string'e danisiyoruz :o) bool sozcukArasi(string::value_type harf) { // Eger bosluksa veya noktalama isaretlerinden // birisiyse 'true' dondurecegiz return isspace(harf) || ispunct(harf); } // Bu fonksiyonu Andrew Koening ve Barbara Moo'nun // "Journal of Object Oriented Programming" dergisinde // (Cilt 13, Sayi 11) "Accelerated C++" adli kitaplarini // tanittiklari yazilarindan uyarladim. Sozcukler parcala(string const & satir) { Sozcukler sozcukler; typedef string::size_type StringBoyutu; StringBoyutu i = 0; while (i != satir.size()) { // Satir basindaki bosluklari atlayalim while ((i != satir.size()) && sozcukArasi(satir[i])) ++i; StringBoyutu j = i; // Bosluk olmayan butun harfler sozcugun parcalari while ((j != satir.size()) && !sozcukArasi(satir[j])) ++j; // Bakalim sozcuk bulabildik mi if (i != j) { // Sozcugu sozcuk dizisinin sonuna ekleyelim sozcukler.push_back(satir.substr(i, j - i)); i = j; } } return sozcukler; } // 'sozcukler' dizisinde bulunan sozcukleri 'dagilim'a ekler void dagilimaEkle(Dagilim & dagilim, Sozcukler const & sozcukler) { typedef Sozcukler::const_iterator Yuruyucu; Yuruyucu const son = sozcukler.end(); for (Yuruyucu y = sozcukler.begin(); y != son; ++y) { string const & sozcuk = *y; // Bu sozcuge ait sayaci bir arttiralim. // Asagidaki satirin guzelligi, ilk goruldugunde // sozcugun dagilima 0 sayacla eklenmesi. Ama // hemen arttirip 1 yapiyoruz. ++dagilim[sozcuk]; } } int main() { // Dagilimi burada toplayacagiz Dagilim dagilim; // Dosyayi satir satir buraya okuyacagiz string satir; while (getline(cin, satir)) { // Satiri sozcuklerine ayirip dagilima ekleyelim Sozcukler const sozcukler = parcala(satir); dagilimaEkle(dagilim, sozcukler); } // Ekrana yazdiralim yazdir(dagilim, cout); // C++ standardi, 'main' fonksiyonundan donerken // bir 'return' satiri kullanilmadiginda // derleyicinin sanki bir 'return 0;' yazilmis gibi // derlemesi gerektigini soyler. MSVC++ bu kurala // uymadigi icin onu memnun etmek icin satiri kendimiz // yaziyoruz. Iyi ki uzun degil... :) return 0; }