[ korisnik07 @ 16.11.2009. 14:23 ] @
"Napisati program koji učitava listu riječi koju zatim ispisuje skupa sa brojem pojavljivanja svake riječi, bez ponavljanja ispisa."

pripremam ispit iz programiranja, i posto se do sad nisam susretao sa Cpp, naisao sam na poteskoce. Gore navedeni zadatak nikako da rijesim, pokusavao sam sa listama, ali ne znam kako da broji svaki posebno unos da li se pojavljuje u listi, i kako da ispisem odredjeni unos iz liste? moze li me neko molim vas usmjeriti sto se tice ovog gore zadatka, hitno je :)
[ djoka_l @ 16.11.2009. 14:52 ] @
Ako ti izraz "associative array" ništa ne znači, problem ćeš rešiti vrlo teško, u suprotnom rešenje je u nekoliko redova...
[ Mihajlo Cvetanović @ 16.11.2009. 15:12 ] @
Ono što ti treba je std::map<std::string, int>. Ako je mapa_stringova ovog tipa onda inkrementiranje broja pojavljivanja nekog stringa nov_string postaje mapa_stringova[nov_string]++. Na kraju rada iteriraš od početka do kraja, i za svaki elemenat na koji se referiše "std::map<std::string, int>::iterator trenutni_iterator" ispiši reč trenutni_iterator->first i njen broj pojavljivanja trenutni_iterator->second.
[ korisnik07 @ 16.11.2009. 16:40 ] @
ništa mi za sad ne znači associative array, ali evo potrudit ću se da naučim šta o tome
[ Goran Arandjelovic @ 16.11.2009. 19:25 ] @
Citat:
djoka_l: Ako ti izraz "associative array" ništa ne znači, problem ćeš rešiti vrlo teško, u suprotnom rešenje je u nekoliko redova...


Da, baš je inače vrlo teško rešiti... odmah da odustane od zadatka ako ne zna šta su asocijativni nizovi... :)
Inače, trebalo je da ponudiš korisniku skicu tog "teškog" rešenja, možda bi mu značilo...

--

@korisnik07

Ako bi recimo hteo pešaka (bez biblioteka) da rešiš problem i to još sa listama recimo kako si inicijalno hteo... evo najjednostavnijeg rešenja:

Code:

struct Node
{
  string rec;
  int broj_ponavljanja;
  Node *prethodni, *sledeci;
};


Tako bi recimo mogla da izgleda lista.

F-je koje bi otprilike trebalo da obezbediš:

Code:

Node *DodajNaKrajListe(Node *lista, const string &rec);
// F-ja PronadjiElement vraća NULL ako ne pronađe datu reč
Node *PronadjiElement(Node *pocetak_liste, const string &rec);
void IspisiListu(Node *pocetak_liste);


Ne mora sve ovako da bude, ali za početak prolazi...

Code:

int main()
{
  Node *pocetak_liste = new Node;
  Node *kraj_liste = pocetak_liste;

  string rec;

  pocetak_liste->prethodni = NULL;
  pocetak_liste->sledeci = NULL;

  while(/*neki uslov za izlazak kad dodjes do poslednje reči za učitavanje*/)
  {
    // učitaj string (rec) odakle već učitavaš...
    // rec = ...

    // linearna pretraga ti je zadovoljavajuća za zadatak sem ako nije drugačije navedeno
    Node *pr = PronadjiElement(pocetak_liste, rec);
    if(pr != NULL)
    {
      pr->broj_ponavljanja++;
    }
    else
    {
      // dodaš na kraj liste i taj kraj vratiš kao povratnu vrednost
      kraj_liste = DodajNaKrajListe(kraj_liste, rec);
    }
  }

  IspisiListu(pocetak_liste);

  // obriši listu...

  return(0);
}


Pisao sam ovo napamet... ali trebalo bi da ti je sada malo jasnije. Ove funkcije bi trebalo da znaš da napišeš...
[ korisnik07 @ 17.11.2009. 20:50 ] @
riješio sam ovo na sljedeći način, ali malo me buni jer je u napomeni prof napisao da ne smijemo koristiti vektore, pa je li postoji drugi način, ovako sličan ali bez vektora... takođe ne smijemo koristiti pokazivače nit išta slično :)

Code:
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main() {
    vector <string> lista;
    vector <int> broj;
    string rijec;
    typedef vector<string>::size_type rijeci;

while(cin >> rijec) {
   if(lista.size()==0) {
      lista.push_back(rijec);
      broj.push_back(1);
} else {
      for(rijeci i = 0;i<=lista.size();i++) {
      if(rijec == lista[i]){
      (broj[i])++;
      break;
}

if(i==(lista.size()-1)) {
      lista.push_back(rijec);
      broj.push_back(1);
      break;
}
}
}
}

cout << "Lista rijeci:\n";
        for(rijeci i=0; i<lista.size(); i++) {
            cout << lista[i] << "\t\t" << broj[i] << endl;
        }
system("PAUSE");
return 0;
}

[ Goran Arandjelovic @ 17.11.2009. 21:01 ] @
Čekaj, smete da koristite klasu string, a ne smete da koristite pokazivače?!
[ korisnik07 @ 17.11.2009. 21:59 ] @
tako ispadne :)
[ Mihajlo Cvetanović @ 17.11.2009. 22:36 ] @
Kao što rekoh, std::map<std::string, int>. Pogledaj help, probaj, videćeš da je to upravo ono što tražiš.
[ Goran Arandjelovic @ 17.11.2009. 23:14 ] @
Reče čovek da ne može da koristi ni std::vector, a verovatno ne ni std::map. Samo mi nije jasno zašto ako već ne mogu da koriste pokazivače, mogu da koriste klasu string... Malo je čudno.


@korisnik07
U principu, u prethodnom primeru vidi da samo umesto vektora koristiš onda obične nizove

Code:

string niz[10000]; // stavi neki max broj stringova


a pošto nemaš više push_back, uvedi neki brojač koji označava koliko elemenata imaš u tom nizu do trenutka unosa nove reči.
[ djoka_l @ 17.11.2009. 23:49 ] @
Btw. pošto se čini da ne smeš da koristiš map, evo kako bi izgledalo rešenje sa map:
Code:
#include <map>
#include <string>
#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
   map<string, int> wordcount;
   string inputword;
   map<string, int>::iterator i;
   
   while( cin >> inputword) wordcount[inputword]+=1;
   
   cout << "Stastistika:" << endl;
   
   for( i = wordcount.begin();  i != wordcount.end();  i++ )
       cout <<  i->first << " : "<< i->second << endl;
   return 0;
}
[ korisnik07 @ 18.11.2009. 12:58 ] @
mislim da je riješeno, hvala mnogo svima!