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

Licznik (funkcje,tablice znaki) - język C

Object Storage Arubacloud
+1 głos
1,031 wizyt
pytanie zadane 13 stycznia 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)
edycja 13 stycznia 2020 przez Hubertius

Cześć, natrafiłem na skomplikowane zadanie i potrzebuję waszej pomocy.

Treść jest taka:

Napisz następujące funkcje:

  • count - funkca zlicza liczbę wystąpień znaku c w ciągu znaków tab,
  • count_string - funkca zlicza liczbę wystąpień ciągu znaków tab2 w tablicy tab,
  • count_all_of - funkca zlicza liczbę wystąpień wszystikich unikalnych znaków z tablicy tab2 w tablicy tab. Unikalność oznacza, że jeśli dany znak występuje w tablicy tab2 więcej niż raz, to jest on tylko raz uwzględniany.
    Przykład: count_all_of("ela, ola i ewa", "ala") == 5, bo unikalne litery w ala to l oraz a natomiast w tekście ela, ola i ewa litera a występuje 3 razy natomiast l występuje 2 razy.

Funkcje mają mieć następujące prototypy:

int count_string(const char tab[], const char tab2[]);
int count_all_of(const char tab[], const char tab2[]);
int count(const char tab[], char c);

Napisz program, który wczyta dwa ciągi znaków i następnie policzy i wypisze w kolejnych liniach:

  • liczbę wystąpień pierwszego znaku z drugiego ciągu w pierwszym ciągu,
  • liczbę wystąpień drugiego ciągu w pierwszym ciągu,
  • łączną liczbę wystąpień unikalnych znaków z drugiego ciągu w pierwszym.

Program powinien wykorzystywać jedynie 1000 pierwszych znaków z obu tekstów.

Uwaga: W programie nie można korzystać z bibliotek stdlib i string oraz z funkcji z rodziny scanf (oprócz funkcji scanf).

Przykładowe wejście:

Podaj tekst:
To jest test
Podaj szukany ciag znakow:
jest

Przykładowe wyjście:

1
1
8

A tutaj podaję swój kod:

#include <stdio.h>
#include <math.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int count_string(const char tab[], const char tab2[]);
int count_all_of(const char tab[], const char tab2[]);
int count(const char tab[], char c);
int main() 
{
	char tablica1[1001]={0};
	printf("Podaj tekst:\n");
	fgets(tablica1,1001,stdin);
	/*char zmienna_tymczasowa_ciuralla='a';

       do
       {
       scanf("%c",&zmienna_tymczasowa_ciuralla);
       }while(zmienna_tymczasowa_ciuralla != '\n');*/
   
	char tablica_poszukiwanych_1[1001]={0};
	printf("Podaj szukany ciąg znakow:\n");
	fgets(tablica_poszukiwanych_1,1001,stdin);
       /*do
       {
       scanf("%c",&zmienna_tymczasowa_ciuralla);
       }while(zmienna_tymczasowa_ciuralla != '\n');*/
    
	int zmienna_pomocnicza_do_spacji=-1;
	do
	{
	  zmienna_pomocnicza_do_spacji++;	
	}while(tablica_poszukiwanych_1[zmienna_pomocnicza_do_spacji]==32);
	char c=tablica_poszukiwanych_1[zmienna_pomocnicza_do_spacji];
	int wynik=0;
	wynik=count(tablica1,c);
	printf("%d",wynik);
	wynik=count_string(tablica1,tablica_poszukiwanych_1);
	printf("\n%d",wynik);
	wynik=count_all_of(tablica1,tablica_poszukiwanych_1);
	printf("\n%d",wynik);
	
	return 0;
}
int count(const char tab[], char c)
{
	int zs_j;
	int count=0;
	int i=0;
	while(tab[i]!='\0')
	{
		i++;
	}
	for(zs_j=0;zs_j<=i;zs_j++)
    {
    	if(tab[zs_j]==c)
    	{
    		//printf("\n%c\n",tab[zs_j]);
    		count++;
		}
    }
    return count;
}
int count_string(const char tab[], const char tab2[])
{
	int i=-1;
	int j=-1;
	do
	{
	  i++;	
	}while(tab2[i]==32);
	int zs_i=i;
	do
	{
	  j++;	
	}while(tab[j]==32);
	int zs_j=j;
	int ile_liter=0;
	while(tab2[i]!='\0')
	{
		if(tab2[i]!=' ')
		{
			//printf("\nZnak: %c , numer litery %d",tab2[i],ile_liter);
			if(tab2[i+1]=='\0')
			{
				break;
			}
		    ile_liter++;
	    }
	i++;
	}
	int count=0;
	int zs_s=0;
	int wynik=0;
	j=zs_j;
	i=zs_i;
	while(tab[j]!='\0')
	{
	   if(tab[j]==tab2[i])
	   {
	   	
	   	  for(zs_s=0;zs_s<ile_liter;zs_s++)
	   	  {
	   	  	if(tab[j+zs_s]==tab2[i+zs_s])
	   	  	{
	   	  		count++;
		    }
		    if(count==ile_liter)
		    {
		    	wynik++;
			}
		  }
		count=0;
	   }
	j++;
	}
	return wynik;
		
}
int count_all_of(const char tab[], const char tab2[])
{
	int i=-1;
	int j=-1;
	do
	{
	  i++;	
	}while(tab2[i]==32);
	int zs_i=i;
	do
	{
	  j++;	
	}while(tab[j]==32);
	int dlugosc_2=0;
	while(tab2[i]!='\0')
	{
		if(tab2[i]!=' ')
		{
			//printf("\nZnak: %c , numer litery %d",tab2[i],ile_liter);
			if(tab2[i+1]=='\0')
			{
				break;
			}
		    dlugosc_2++;
	    }
	i++;
	}
	int wynik=0;
	i=zs_i;
	int zs_j=j;
	
	int negatywnie=0;
     while(tab2[i]!='\0')
    {
    	for(j=zs_j;tab[j]!='\n';j++)
    	{
    		if(tab2[i]==tab[j])
    		{
    			 int dekrementacja;
    			  for(dekrementacja=i;dekrementacja>=zs_i+1;dekrementacja--)
    			  {
    			  	   if(tab2[dekrementacja]==tab2[dekrementacja-1])
    			  	   {
    			  	   	 negatywnie++;
					   }
				  }
				  if(negatywnie==0)
				  {
				  	wynik++;
				  }
				  negatywnie=0;		 
			}
		}
	i++;
    
	}
	 

	return wynik;
	
}

Mój problem jest właśnie związany z funkcjami string i all_off.

Do możliwości sprawdzenia poprawności zadania wykonuję testy. U funkcji string wysypuje się na około 1/3 testów podlegających jej samej. Podaję przykłady, dla których to się dzieje:

-1 przykład

printf("#####START#####");
                int len = count_string("\na", "a");
                printf("#####END#####\n");
                test_error( len == 1, "Funkcja count_string zwróciła nieprawidłową wartość, powinna zwrócić 1, a zwróciła %d", len);

Tu mi pokazuje infromację, że funkcja powinna zwrócić 1, a zwróciła 0.

-2 przykład

printf("#####START#####");
                int len = count_string("beganJobs offshoring began with manufacturing, but the rise of the high-speed Internet made it possible to move offshore tradable professional skills, such as software engineering, information technology, various forms of engineering, architecture, accounting, and even the medical reading of MRIs and CT-Scans. - Paul Craig Robertsbegan\nJobs offshoring began with manufacturing, but the rise of the high-speed Internet made it possible to move offshore tradable professional skills, such as software engineering, information technology, various forms of engineering, architecture, accounting, and even the medical reading of MRIs and CT-Scans. - Paul Craig Roberts", "began\n");
                printf("#####END#####\n");
                test_error( len == 1, "Funkcja count_string zwróciła nieprawidłową wartość, powinna zwrócić 1, a zwróciła %d", len);

Tu mi pokazuje infromację, że funkcja powinna zwrócić 1, a zwróciła 4.

-3 przykład

printf("#####START#####");
                int len = count_string("I solemnly swear that I am up to no good. - J.K. Rowling", "I\n");
                printf("#####END#####\n");
                test_error( len == 0, "Funkcja count_string zwróciła nieprawidłową wartość, powinna zwrócić 0, a zwróciła %d", len);

Tu mi pokazuje infromację, że funkcja powinna zwrócić 0, a zwróciła 2.

Bardzo proszę o podpowiedź, bo czuję, że niewiele brakuje mi poprawić kod tej funkcji.

No i teraz przechodzę do funkcji all_off

int count_all_of(const char tab[], const char tab2[])
{
	int i=-1;
	int j=-1;
	do
	{
	  i++;	
	}while(tab2[i]==32);
	int zs_i=i;
	do
	{
	  j++;	
	}while(tab[j]==32);
	int dlugosc_2=0;
	while(tab2[i]!='\0')
	{
		if(tab2[i]!=' ')
		{
			//printf("\nZnak: %c , numer litery %d",tab2[i],ile_liter);
			if(tab2[i+1]=='\0')
			{
				break;
			}
		    dlugosc_2++;
	    }
	i++;
	}
	int wynik=0;
	i=zs_i;
	int zs_j=j;
	
	int negatywnie=0;
     while(tab2[i]!='\0')
    {
    	for(j=zs_j;tab[j]!=13';j++)
    	{
    		if(tab2[i]==tab[j])
    		{
    			 int dekrementacja;
    			   for(dekrementacja=i-1;dekrementacja>=zs_i;dekrementacja--)
                  {
            
                         if(tab2[i]==tab2[dekrementacja])
                         {
        
                              negatywnie++;
                       }
                  }
				  if(negatywnie==0)
				  {
				  	wynik++;
				  }
				  negatywnie=0;		 
			}
		}
	i++;
    
	}
	 

	return wynik;
	
}

Założenie było proste. Gdy element drugiej tablicy według której szukamy był równy elementowi z pierwszej pętla

 for(dekrementacja=i-1;dekrementacja>=zs_i;dekrementacja--)
                  {
            
                         if(tab2[i]==tab2[dekrementacja])
                         {
        
                              negatywnie++;
                       }
                  }

miała sprawdzać, czy poprzednie elementy tablicy drugiej (czyli ciągu, według którego "przeszukujemy" pierwszy) są równe obecnemu elementowi. Jeżeli tak, to negatywnie miała się zwiększyć o jeden, a tym samym wynik końcowy miał nie ulegać "fałszywemu" zwiększeniu. No... tylko coś się spierdaczyło (i raczej jest to mój błąd logiczny) i o ile znaki zlicza, o tyle nie działa prawidłowo przy sprawdzeniu powtórzeń. 

Proszę bardzo o pomoc, z góry dziękuję za wszelkie odpowiedzi, które pomogą mi w rozwiązaniu zadania.

1 odpowiedź

0 głosów
odpowiedź 14 stycznia 2020 przez j23 Mędrzec (194,920 p.)
edycja 14 stycznia 2020 przez j23

Uprościłem nieco count_string:

int count_string(const char tab[], const char tab2[])
{
    int n = 0;
    const char* p = tab;
    
    while (*p != 0) {        
        int i = 0;
        
        while (tab2[i] != 0 && tab2[i] == p[i]) ++i;
        
        if (tab2[i] == 0) { ++n; p += i; }
        else ++p;
    }
    
    return n;  
}

 

--- dodane ---

a to jeszcze count_all_of:

int count_all_of(const char tab[], const char tab2[])
{
    int charFreqs[256] = { 0 };
    
    for (int i = 0; tab[i]; ++i) {
        ++charFreqs[(unsigned)tab[i]];
    }
    
    int n = 0;
    
    for (int i = 0; tab2[i]; ++i) {
        int cc = charFreqs[(unsigned)tab2[i]];
        charFreqs[(unsigned)tab2[i]] = 0;
        if(cc > 1) n += cc;
    }
    
    return n;    
}

 

Podobne pytania

0 głosów
1 odpowiedź 1,300 wizyt
pytanie zadane 13 listopada 2019 w C i C++ przez disi22 Początkujący (300 p.)
+1 głos
2 odpowiedzi 200 wizyt
pytanie zadane 27 listopada 2018 w C i C++ przez Levy Nowicjusz (240 p.)
0 głosów
1 odpowiedź 1,154 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!

...