• 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

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
+1 głos
891 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 (22,220 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,340 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,340 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ź 977 wizyt
pytanie zadane 5 grudnia 2021 w Java przez xTMx3 Obywatel (1,560 p.)
+1 głos
1 odpowiedź 541 wizyt
pytanie zadane 9 maja 2021 w C i C++ przez nzepik324 Początkujący (260 p.)
0 głosów
0 odpowiedzi 947 wizyt

93,187 zapytań

142,203 odpowiedzi

322,023 komentarzy

62,513 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2581p. - dia-Chann
  2. 2537p. - Łukasz Piwowar
  3. 2528p. - Łukasz Eckert
  4. 2514p. - CC PL
  5. 2445p. - Łukasz Siedlecki
  6. 2443p. - rucin93
  7. 2252p. - Tomasz Bielak
  8. 2201p. - Michal Drewniak
  9. 2156p. - Marcin Putra
  10. 2152p. - Adrian Wieprzkowicz
  11. 2105p. - Mikbac
  12. 1941p. - Anonim 3619784
  13. 1733p. - rafalszastok
  14. 1480p. - Michał Telesz
  15. 1469p. - ssynowiec
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...