• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

zliczanie poszczególnych liter z pliku język C

+1 głos
115 wizyt
pytanie zadane 16 stycznia w C i C++ przez Dynamic Bywalec (2,810 p.)

Witam, mam policzyć ilosc poszczególnych liter w pliku *.txt

napisałem coś takiego:

while((c=fgetc(f))!=EOF)
        {
            if((c==97) || (c==65))
                a++;
            if((c==98) || (c==66))
                b++;
        }

ale muszę wypisać if do każdej litery to trochę czasu to zajmuje. Ma ktoś pomysł, jak to zrobić inaczej?

2 odpowiedzi

+1 głos
odpowiedź 16 stycznia przez overcq Pasjonat (17,750 p.)

Możesz wykorzystać to, że w tabeli ASCII mała i duża litera jest odległa o taką samą wartość w ciągłym zakresie. I przypisać do tablicy. Na przykład:

if( c >= 65 && c <= 90 )
    tablica[ c - 65 ]++;
else if( c >= 97 && c <= 122 )
    tablica[ c - 97 ]++;

 

0 głosów
odpowiedź 16 stycznia przez profesorek96 Szeryf (91,020 p.)

Rozwiązanie za pomocą wielu wyrażeń warunkowych jest bardzo czasochłonne i nie efektywne. Wykorzystał bym fakt że każdy znak w komputerze ma jakiś swój unikalny numer. Weźmy np. kodowanie ASCII tam literze a przypisuje się numer 97 zaś litera A kodowana jest jako liczba 65. Jeśli chciałbyś zliczać wszystkie znaki z ASCII to musiał byś stworzyć tablicę 256 elementów wypełnioną zerami. Indeks tej tablicy odpowiadał by numerowi znaku z ASCII. Zaś wartość jaka była by pod danym indeksem to jest liczba ile razy dany znak się powtórzył.

W twoim przypadku, jeśli chcesz zliczać tylko litery to wystarczyła by ci tablica 26 element-owa. Ewentualnie dwie tablicy jeśli chciałbyś rozróżniać czy to jest mała czy duża litera. Przykładowy kod realizujący takie zliczanie dostępny jest poniżej:

#include <stdio.h>

int main()
{
	char * nazwa="plik.txt";
	FILE *plik=fopen(nazwa,"r");
	int alfabet_duzy[26]={0};
	int alfabet_maly[26]={0};
	if(plik!=NULL)
	{
		char znak;
		while((znak=fgetc(plik))!=EOF)
        {
            if(znak>='A' && znak<='Z')
			{
				alfabet_duzy[znak-'A']++;
			}
			else if(znak>='a' && znak<='z')
			{
				alfabet_maly[znak-'a']++;
			}
        }
		fclose(plik);
		printf("Litery male:\n");
		for(int i=0;i<26;i++)
		{
			if(alfabet_maly[i]!=0)
			{
				printf("%c:%d\n",i+'a',alfabet_maly[i]);
			}
		}
		printf("\nLitery duze:\n");
		for(int i=0;i<26;i++)
		{
			if(alfabet_duzy[i]!=0)
			{
				printf("%c:%d\n",i+'A',alfabet_duzy[i]);
			}
		}
	}	
	else
	{
		printf("Problem z plikiem!!!\n");
		return 1;
	}
	return 0;
}

 

2
komentarz 16 stycznia przez Oscar Nałogowiec (25,590 p.)
edycja 16 stycznia przez Oscar
Lepiej w ogóle zrezygnować z rozpoznania czegokolwiek w momencie czytania i zrobić klasyczny histogram. 256 liczników, nawet 64-bitowych  to raptem 2KB. A łączne zsumowanie małych i wielkich liter można wykonać w czasie wypisywania:

histogram['a'] + histogram['A'];

Lepiej uprościć i przyspieszać pętle, która może się wykonać i miliard razy (plik 1GB) a nie jednorazowe obliczenia przy wypisywaniu (26 liter).

 

PS. Kod wyżej będzie działał nieprawidłowo jeśli natrafi na znak o kodzie 255 - zatrzyma się.
komentarz 16 stycznia przez profesorek96 Szeryf (91,020 p.)
Oczywiście że można zrobić to na tablicy o rozmiarze 256. Czemu twoim zdaniem powyższy kod będzie działał nieprawidłowo dla znaku o kodzie 255. Testowałem na tak owym znaku, nic się nie dzieje. Zlicza wszystko poprawnie. Znak o kodzie 255 jest ignorowany.
komentarz 16 stycznia przez Oscar Nałogowiec (25,590 p.)

Zasugerowałem się typem zmiennej znak. Dałeś char - pamiętam, że pare razy miałem z tym problem, getc daje int - wynik 0-255 jak wczyta znak lub EOF (-1) jak nie może. Char to za mało na rozróżnienie, ale może zapis tego w jednym wyrażeniu będzie OK. Zależy co zwraca operator "=" smiley Jeśli zwróci int będzie OK.

Podobne pytania

0 głosów
1 odpowiedź 153 wizyt
pytanie zadane 5 grudnia 2021 w Java przez xTMx3 Obywatel (1,320 p.)
+1 głos
1 odpowiedź 121 wizyt
pytanie zadane 9 maja 2021 w C i C++ przez nzepik324 Początkujący (260 p.)
0 głosów
0 odpowiedzi 562 wizyt

88,311 zapytań

136,904 odpowiedzi

305,517 komentarzy

58,593 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...