• 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

Object Storage Arubacloud
+1 głos
641 wizyt
pytanie zadane 16 stycznia 2022 w C i C++ przez Dynamic Bywalec (2,910 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 2022 przez overcq Pasjonat (21,710 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 2022 przez profesorek96 Szeryf (91,420 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 2022 przez Oscar Nałogowiec (29,320 p.)
edycja 16 stycznia 2022 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 2022 przez profesorek96 Szeryf (91,420 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 2022 przez Oscar Nałogowiec (29,320 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ź 742 wizyt
pytanie zadane 5 grudnia 2021 w Java przez xTMx3 Obywatel (1,560 p.)
+1 głos
1 odpowiedź 349 wizyt
pytanie zadane 9 maja 2021 w C i C++ przez nzepik324 Początkujący (260 p.)
0 głosów
0 odpowiedzi 805 wizyt

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...