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?
Ale o czym ty mówisz? Przecież SPOJ podaje ci dane w na stdin a nie przez żaden plik.
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?
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?
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...
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?
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.
Wybacz mi moją niewiedzę, ale to są moje początki z programowaniem. Mógłbyś napisać jaśniej jak to zrobić?
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.
A to nieoptymalne wyjście?
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.
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ą?
Shalom, mógłbyś to ubrać w kod?
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).
Czyli najpierw posortować, a potem to, co napisałeś, tak?
Mniej więcej ;]
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
}
}
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();
}
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.
Mam podobny problem z tym programem, czy ktoś może wrzucić błędy w tym programie?