Sortowanie i zliczanie danych pobranych z pliku

0

Mam do napisania taki program: http://pl.spoj.pl/problems/NAMES/
Jak powinien wyglądać kod zapewniający dostęp do pliku i wczytujący tylko imiona?

0

Ale o czym ty mówisz? Przecież SPOJ podaje ci dane w na stdin a nie przez żaden plik.

0

To jest treść zadania, które mam napisać w C. Jak mam stworzyć tablicę, zawierającą listę samych imion, które są w pliku tekstowym?

0

Nie uczą was w podstawówce jak formułować pytania?
Rozumiem że chcesz napisać program który wczytuje z pliku informacje na temat osób i ma z tych informacji wyselekcjonować same imiona. Tak?

0

Mam coś takiego:

FILE *plik;
plik=fopen("dane.txt","r");

struct {
char[20] imie
} imiona[T]

i=0;
while(fscanf(plik, "%*s %*s %s", &imiona[i].imie)==1) i++;

Teraz muszę wszystkie litery zmienić na duże...

0

No dobra. Teraz chyba najtrudniejsze. Jak mam zliczyć wystąpienia imion i uzyskać na wyjściu coś takiego, np:
ANNA X
PAWEŁ Y
PIOTR Z
gdzie X,Y,Z to ilości wystąpień tych imion?

0

Optymalnie? Zrób tablicę hashującą która odwzorowuje imie -> ilość wystąpień.
Wtedy wystarczy ci

tablica[hashuj(imie)]++;

Nieoptymalnie możesz po prostu posorotować te imiona i przechodząc przez tablicę liczyć ile razy wystąpiło dane imie.

0

Wybacz mi moją niewiedzę, ale to są moje początki z programowaniem. Mógłbyś napisać jaśniej jak to zrobić?

0

Ok, tutaj masz przykład funkcji hashującej. Nie jest najlepsza, ale powinna starczyć

const int modulo = 91; //ile ma być pól w tablicy

int hash(const char* slowo)
{
  int ret=0;
  unsigned int n=strlen(slowo);

  while(n>=sizeof(int))
  {
   ret^=*(int*)slowo;
   n-=sizeof(int);
   slowo+=sizeof(int);
  }

  int rem=0;
  while(n--)
  {
    rem<<=8;
    rem^=*slowo++;
  }
  ret^=rem;
  return ret%modulo;
}

Ta funkcja zamienia słowo na liczbę. Minusem tablicy hashującej są konflikty (dla dwóch różnych słów możemy mieć taką samą wartość). Proponuje użyć tutaj rozwiązywania konfliktów za np. pomocą listy synonimów.

0

A to nieoptymalne wyjście?

0

W nieoptymalnym cudów nie ma. Sortujesz sobie tą swoją tablicę z imionami, więc masz np. coś takiego:
Ala
Ala
Ala
Ola
Ola
Ela
Ela
Ela
Ela

I nie jest zbyt skomplikowane policzenie ile jest których. Lecisz od początku i zliczasz aż nie trafisz na inne imie. Wtedy wypisujesz wynik i zaczynasz liczyć od nowa.

0

Tyle mam:

FILE *plik;
plik=fopen("dane.txt","r");

struct {
char[20] imie
} imiona[T]

i=0;
while(fscanf(plik, "%*s %*s %s", &imiona[i].imie)==1) i++;

while (&imiona[i].imie)
{
      c=&imiona[i].imie;
      putchar (toupper(c));
      i++
}

Czy jest ktoś w stanie jasno napisać jak mam zliczyć wystąpienie poszczególnych imion, a wypadku kiedy będzie taka sama ilość, ułożyć alfabetycznie te z tą samą ilością?

0

Shalom, mógłbyś to ubrać w kod?

0

Sortowanie:
http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/
Potem robimy sobie elengancko tablicę struktur

struct wynik
{
  char* imie;
  int ilosc;
}wyniki[X];

A potem wystarczy coś takiego:

char* aktualny = tablica[0];
strcpy(wyniki[0].imie,aktualny);
int j=0;
for(int i=0;i<iloscImion;i++)
{
  while(strcmp(aktualny, tablica[i])==0)
  {
    wyniki[j].ilosc++;
    j++;
  }
  aktualny = tablica[i];
}

(pisane z palca, mogą być jakieś błędy).

0

Czyli najpierw posortować, a potem to, co napisałeś, tak?

0

Mniej więcej ;]

0

Mam coś takiego. Bardzo proszę o poprawienie błędów, bo nie rozumiem tego, co mi kompilator wyrzuca. Tyle ile byłem w stanie, poprawiłem.
No i jeszcze jak ma mi wypisać wynik działania?
W załączniku beztytułu2 screen błędów

#include <stdio.h>
#include <stdlib.h>

int porownaj (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}


int main()
{
int i;
//stworzenie struktury i wczytanie imion       
FILE *plik;
plik=fopen("dane.txt","r");

struct {
char imie[20];
} imiona[i];

i=0;
while(fscanf(plik, "%*s %*s %s", &imiona[i].imie)==1) i++;


//konwersja na wielkie litery
char c;

while (imiona[i]) // 1 błąd
{
      c=imiona[i].imie;  //2 błąd
      putchar (toupper(c));
      i++;
}

//sortowanie
int n;
qsort (imiona, i, sizeof(int), porownaj);
for (n=0; n<i; n++)
printf("%d ", imiona[n]);
return 0;

//zliczanie
int x,k;
char tablica[k];
struct wynik
{
  char* imie;
  int ilosc;
}wyniki[x];

char* aktualny = tablica[0];  //3 błąd
strcpy(wyniki[0].imie,aktualny);
int j=0;
int iloscImion;
for(int p=0;p<iloscImion;p++)  //4 błąd
{
  while(strcmp(aktualny, tablica[p])==0) //5 błąd
  {
    wyniki[j].ilosc++;
    j++;
  }
  aktualny = tablica[p]; //6 błąd
}

}

0

Kompilator już nie wyrzuca błędów, program się wykonuje w nieskończoność i pokazuje nie wiadomo co.

#include <stdio.h>
#include <stdlib.h>

int porownaj (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}


int main()
{
int i;
//stworzenie struktury i wczytanie imion       
FILE *plik;
plik=fopen("dane.txt","r");

struct {
char imie[20];
} imiona[100000];

i=0;
while(fscanf(plik, "%*s %*s %s", &imiona[i].imie)==1) i++;


//konwersja na wielkie litery
char *c;

while (imiona)
{
      c=(imiona[i].imie);
      putchar (toupper(c));
      i++;
}

//sortowanie
int n;
qsort (imiona, i, sizeof(int), porownaj);
for (n=0; n<i; n++)
printf("%d ", imiona[n]);
return 0;

//zliczanie
int x,k;
char *tablica[k];
struct wynik
{
  char* imie;
  int ilosc;
}wyniki[x];

char* aktualny = tablica[0];
strcpy(wyniki[0].imie,aktualny);
int j=0;
int iloscImion;
int p;
for(p=0;p<iloscImion;p++)
{
  while(strcmp(aktualny, tablica[p])==0)
  {
    wyniki[j].ilosc++;
    j++;
  }
  aktualny = tablica[p];
}
getchar();
}

0

sizeof(int) ?
a nie czasem sizeof(char)?
Deklaracja struktury raczej nad main()...
char *tablica[k]; ? WTF? Miałeś korzystać z tej tablicy z imionami!
iloscImion to miała być ZNANA WARTOŚĆ, w twoim przypadku jak rozumiem jest to zmienna 'i'
MYŚL.

0

Mam podobny problem z tym programem, czy ktoś może wrzucić błędy w tym programie?

1 użytkowników online, w tym zalogowanych: 0, gości: 1