| Uutiset | Koodikirjasto | Wiki | Keskustelut | FAQ | Info |
Palindromin etsiminen, C vs C++/STLempty 16.03.03 20:33 Kaksi eri funktiota testaamaan onko sana palindromi. Toinen on perinteistä C:tä, toinen näyttää kuinka näppärästi homma hoituu STL:n avulla.
////////////////////////////////////////////////////////////////////////// /// Kaksi eri funktiota testaamaan onko sana palindromi. /// /// Toinen on perinteistä C:tä, toinen näyttää kuinka näppärästi homma /// hoituu STL:n avulla. /// /// Isoja ja pieniä kirjaimia ei eritellä, ja vain kirjaimet otetaan /// huomioon. Esim "AB 21ba.." on palindromi tämän mukaan. /// /// Koodi on ylikommentoitua jotta siitä oppisikin jotain. /// Ehkä vielä voisi mainita C-friikkien huojennukseksi että /// STL-versio on huomattavasti hitaampi. C-versio /// perustuu alkuperäisen tekstin tarkasteluun kun taas /// STL-versio tekee siitä kopion jota se muokkaa /// sopivaksi. /// /// Hannu Kankaanpää 2003 (hkankaan@cc.hut.fi) ////////////////////////////////////////////////////////////////////////// #include <string> #include <algorithm> #include <functional> #include <iostream> #include <cctype> using namespace std; /// C-versio. /// Toimii niin että tekstiä lähdetään tutkimaan alusta loppuun /// ja samalla lopusta alkuun päin ja joka askeleella verrataan /// ovatko merkit samoja. Jos eivät ole, palautetaan 'false'. Jos /// taas tekstistä saadaan tutkittua puolet, niin kyseessä on /// palindromi ja palautetaan 'true'. bool isPalindrome1(const char* text) { // yksi osoitin lähtee tekstin alkupäästä etenemään loppua kohti const char* pFront = text; // toinen osoitin lähtee lopusta alkua kohti const char* pBack = text + strlen(text) - 1; // alkupään merkkejä verrataan loppupään merkkeihin kunnes // osoittimet ohittavat toisensa. while (pBack >= pFront) { // jos alkupään osoitin osoittaa muuhun kuin kirjaimeen, // sitä liikutetaan eteenpäin if (!isalpha(*pFront)) { pFront++; } // vastaava testi loppupään osoittimelle else if (!isalpha(*pBack)) { pBack--; } else { // jos alkupään merkki ei vastaa loppupään merkkiä // niin palautetaan 'false'. toupper:ia käytetään jotta // kirjaimen koolla ei olisi väliä 'a' => 'A', 'A' => 'A' if (toupper(*pFront) != toupper(*pBack)) { return false; } // liikuta kumpaakin osoittimista pFront++; pBack--; } } return true; } /// C++/STL-versio: bool isPalindrome2(string text) { // Tässä aluksi poistetaan merkit jotka eivät ole kirjaimia. // remove_if() ei itsessään poista merkkejä vaan siirtää ne merkkijonon loppuun. // Sen takia on kutsuttava text.erasea poistamaan merkit remove_if:n palauttamasta // iteraattorista tekstin loppuun saakka. // remove_if:n kaksi ekaa parametria kertovat välin jolla merkkejä käsitellään, // eli tässä tapauksessa koko merkkijono alusta loppuun (begin() => end()) // remove_if:n kolmas parametri lienee hieman hämärä. Siis not1(ptr_fun(isalpha)). // isalpha on osoitin funktioon, joten se täytyy kääriä luokan ympärille ptr_fun:n // avulla. Näin not1-predikaatti osaa käyttää sitä. not1 ottaa negaation yhden // argumentin vaatimasta funktiosta (isalpha). text.erase( remove_if(text.begin(), text.end(), not1(ptr_fun(isalpha))) , text.end()); // Nyt muutetaan kaikki merkit isoiksi kirjaimiksi. // transform käy kaikki merkit läpi (text.begin() => text.end()) ja kutsuu // jokaiselle funktiota toupper. Kolmas parametri (text.begin() uudestaan) // kertoo minne toupper:n lopputulos (eli iso merkki) sijoitetaan. Tässä // tapauksessa se sijoitetaan takaisin entiselle paikalleen. transform(text.begin(), text.end(), text.begin(), toupper); // Sitten palautetaan vertailun tulos, eli ovatko merkit alusta loppuun // samoja. Aloitetaan siis text.begin():stä ja mennään text.end():iin, // ja verrataan näitä merkkejä loppupäästä luettaviin merkkeihin. // text.rbegin() siis palauttaa iteraattorin joka käy tekstin läpi lopusta // alkuun. return equal(text.begin(), text.end(), text.rbegin()); } // Pieni testiohjelma tähän lopuksi. int main() { cout << "Onko Saippuakauppias palindromi?\n"; cout << (isPalindrome1("Saippuakauppias") ? "Juu" : "Ei") << endl; cout << "Onko \"Innostunut sonni\" palindromi?\n"; cout << (isPalindrome2("Innostunut sonni") ? "Juu" : "Ei") << endl; cout << "Onko jee palindromi?\n"; cout << (isPalindrome2("jee") ? "Juu" : "Ei") << endl; } empty 20:35 16.3.03 Okei ennenkuin joku pääsee sanomaan, ei toi ensimmäinen funktio ihan C:tä ole kuitenkaan. Käsittääkseni C:ssä ei ollut const-määritettä. ane 07:40 17.3.03 Kyllä, C:ssä on const-määrite. Anylo 15:59 18.3.03 Ihan ok esimerkki STL:stä Linkku 15:03 10.5.04 Hienoa! |
![]() Haku
|