żeby .length() nie zliczała spacji ?

0

Mam problem z tym zadaniem.

Wejście:

Na wejściu program wczytuje łańcuch liter o długości nie większej niż 10 znaków. Następnie wczytuje liczbę n (0<n<10) oznaczającą liczbę napisów do przetestowania. W kolejnych n liniach znajdują się owe napisy. Długość napisu nie przekracza 100 znaków. Należy zliczyć liczbę wystąpień każdej litery z wejścia w każdym podanym napisie.

Wyjście:

Program wypisuje dla każdego napisu liczbę wystąpień każdej litery w osobnych liniach w formacie: "litera:liczba_wystapien".

Przykład:
Wejście:
as
2
ala ma kota
marysia ma rysia

Wyjście:
a: 4
s: 0
a: 4
s: 2

Wiem, że problem w moim programie leży zapewne w funkcji .length() która zliczając znaki bierze rownież spacje pod uwagę co skutkuje błędem w pętli while i problemem z programem. Zamieszczę to co mam i może ktoś będzie umiał mi pomóc.

#include <cstdlib>
#include <iostream>
#include <string>
 
using namespace std;
 
int iw(string napis, char litera)
{
int liczba=0;
     for(int i=0; i<napis.length(); ++i)
     {
             if(napis[i]==litera) ++liczba;
     }
     return liczba;
}
 
int main()
{
    string zdanie;
    string litery;
    int lt=1;
    int tab[10][10];
    do{getline(cin,litery);}
    while(litery.length()>10);//problem
    do{cin>>lt;}
    while(lt>10&&lt<0);//Problem
    cin.get();
    for(int j=0; j<lt; ++j)
    {
                do{getline(cin,zdanie);}
                while(zdanie.length()>100);//Problem
            for(int i=0; i<litery.length(); ++i)
            {
             tab[j][i]=iw(zdanie,litery[i]);    
            } 
    }
    for(int p=0; p<lt; p++)
    {
             for(int k=0,i=0; k<litery.length(),i<litery.length(); ++k,++i)
             {
                     cout<<litery[k]<<":"<<tab[p][i]<<endl;
                     if(k>(litery.length()-1))k=0; 
             } 
    }  
    return 0;
}
0

Widze zadanie jak na spoju. Zapoznaj sie z funkcjami isalpha isdigit isspace. Ja mialem troche inne warunki zadania. Mozesz sobie porownac moj kod.

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    int testy;
    char zdanie[201];
    char alfabet[52];
    int ile[52]={0};
    for(int i=0;i<52;i++)
    {
        if(i<26)
        {
            alfabet[i]=i+97;
        }
        else alfabet[i]=i+39;
    }
    cin >> testy;
    cin.ignore();
    while(testy--)
    {
        cin.getline(zdanie,200);
        for(int i=0;i<strlen(zdanie);i++)
        {
            if(isalpha(zdanie[i]))
            {
                if(isupper(zdanie[i]))
                {
                    ile[zdanie[i]-39]++;
                }
                else if(islower(zdanie[i]))
                {
                    ile[zdanie[i]-97]++;
                }
            }
        }
    }
    for(int i=0;i<52;i++)
    {
        if(ile[i]!=0)
        {
            cout << alfabet[i] << " " << ile[i] << endl;
        }
    }
    return 0;
}
0

Udało mi się rozwiązać problem, zwykłym ifem. ale sprawdzarka nadal nie akceptuje mojego rozwiązania uważając, że jest "zła odpowiedź". Mógł by ktoś zobaczyć o co chodzi ?

#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;
 
int iw(string napis, char litera)
{
int liczba=0;
     for(int i=0; i<napis.length(); ++i)
     {
             if(napis[i]==litera) ++liczba;
     }
     return liczba;
}
 
int main()
{
    string zdanie;
    string litery;
    int lt=0,tab[10][10],liczba[100]={0};
    do{getline(cin,litery);}
    while(litery.length()>10);
    do{cin>>lt;}
    while(lt>10&&lt<0);
    cin.get();
    for(int j=0; j<lt; ++j)
    {
                getline(cin,zdanie);
                                   for(int d=0; d<100; ++d)
                                   {
                                           if(zdanie[d]!=' ')++liczba[d];
                                   }
                                           if(liczba[j]>100)
                                           {
                                                         --j;
                                                         continue;
                                           }
                                           for(int i=0; i<litery.length(); ++i)
                                           {
                                                   tab[j][i]=iw(zdanie,litery[i]);    
                                           } 
    }
    for(int p=0; p<lt; p++)
    {
             for(int k=0,i=0; k<litery.length(),i<litery.length(); ++k,++i)
             {
                     cout<<litery[k]<<":"<<tab[p][i]<<endl;
                     if(k>(litery.length()-1))k=0; 
             } 
    }  
    return 0;
}
0

Pare uwag jesli chodzi o spoja. Warunki zadania sa dla Ciebie jedynie wiadomoscia w przypadku np. wystepowania liczb rzedu 2^64, w jaki sposob zabrac sie za program. Nie musisz sprawdzac dlugosci wyrazow, ani ogolnych warunkow, bo one na pewno wystapia. Czasami jedynie zadanie kaze cos wypisac w pewnych przypadkach, ale tylko jesli jest to sprecyzowane. Takze ten while sprawdzajacy itd. sa zbedne.

Nastepna rzecz. Lepiej jest wczytac powiedzmy 1 test i Od razu wypisac odpowiedz, zamiast tablicowac wyniki, a potem dopiero je wypisywac. Przyjmuje takie odpowiedzi bez problemu i oszczedzasz pamiec. Jak kolega napisac w komentarzu co to ma byc za warunek x>10 i x<0. Toz to jest zbior pusty.

Ja bym zrobil to tak ze do 1 stringa wczytuje sobie slowo podstawowe. Potem tworze na tej podstawie tablice intow wypelniona zerami i zliczam odpowiednie znaki w zaleznosci co dostane na wejsciu. Tak samo jak mam w swoim kodzie wyzej.

Testy wywolujesz najprosciej w petli while tak jak ja to mam. Troche to czytelniejsze.

0

Takie coś daje poprawną odp nie wiem czy działa na spoju ; p

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string *zdania, znaki, *powtorzenia;
	int dlugoscZdania, dlugoscZnaki, liczbaTestow, zliczaj, len;
	cin >> znaki >> liczbaTestow;
	zdania = new string[liczbaTestow];
	powtorzenia = new string[liczbaTestow];
	for(int i = 0; i < liczbaTestow; i++)
	{
		cin.sync();
		getline(cin,zdania[i]);
	}
	dlugoscZnaki = znaki.length();
	for(int i = 0; i < liczbaTestow; i++)
	{
		dlugoscZdania = zdania[i].length();
		for(int j = 0; j < dlugoscZdania; j++)
		{
			
			for(int k = 0; k < dlugoscZnaki; k++)
			{
				if(znaki[k] == zdania[i][j])
					powtorzenia[i] += znaki[k];
			}
		}
	}
	for(int i = 0; i < liczbaTestow; i++)
	{
	    len = powtorzenia[i].length();
		for(int k = 0; k < dlugoscZnaki; k++)
		{
			zliczaj = 0;
			for(int j = 0; j < len; j++)
			{
				if(znaki[k] == powtorzenia[i][j])
					zliczaj++;
			}
			cout << znaki[k] << ":" << zliczaj << "\n";
		}
		cout << "---------\n";
	}

	delete [] zdania;
	delete [] powtorzenia;
    cin.sync();
    cin.get();
    return 0;
}
 
0

Pare uwag jesli chodzi o spoja. Warunki zadania

No tak, ale po tym jak za pierwszym razem program nie był akceptowany to myślałem, że to jest problemem dlatego dałem te wszystkie niepotrzebne jak mówisz pętle.

1 test i Od razu wypisac odpowiedz, zamiast tablicowac wyniki

powód ten sam co wyżej.

Ja bym zrobil to tak ze...

Faktycznie, może i było by wydajniejsze, ale to chyba nie różni się o tyle z poprawką z dołu, aby sp. tego nie akceptowała, a jak wróciłem o 14, tak siedzę, przy tego typu zadaniach i już nie mam siły na to patrzeć a zostało mi to i jeszcze jedno resztę mam, czy da się jakoś poprawnie zmodyfikowac ten progr. czy napisać od nowa tak jak mówiłeś i napisałeś swój progrm. itd. ?

#include <cstdlib>
#include <iostream>
#include <string>
 
using namespace std;
 
int iw(string napis, char litera)
{
int liczba=0;
     for(int i=0; i<napis.length(); ++i)
     {
             if(napis[i]==litera) ++liczba;
     }
     return liczba;
}
 
int main()
{
    string zdanie;
    string litery;
    int lt=0,liczba[100]={0};
    getline(cin,litery);
    cin>>lt;
    cin.get();
    for(int j=0; j<lt; ++j)
    {
                getline(cin,zdanie);
                for(int t=0; t<litery.length(); ++t)
                {
                        cout<<litery[t]<<":"<<iw(zdanie,litery[t])<<endl;   
                }
                 
    }
    return 0;
}
0

Daj link do zadania sprawdze moze mam zrobione xD Najpierw skoncze rundke LoLa potem Ci pomoge ^^

0

Myslalem o spoju ;p nie o wklejce xD

0

i tak nic więcej tam nie ma nawet bez loginu nie wyślesz, żeby spr.

0

Sprawdz to. Jeszcze zastanawia mnie przypadek co kiedy na wejsciu jako wyraz kontrolny dostaniesz powiedzmy "aaa". Wtedy trzebaby chyba wejscie przerobic na samo a bo mamo tylko jedna litere. W takich przypadkach niestety wypisuje 3x a=cos. Mozliwe ze to jest bledem.

#include <iostream>
#include <cstring>

using namespace std;

int szukaj(char napis[], char litera)
{
    short int licznik=0;
    for(unsigned i=0;i<strlen(napis);i++)
    {
        if(napis[i]==litera)licznik++;
    }
    return licznik;
}

void usun_powtorki(char napis[])
{
    for(int i=0;i<strlen(napis)-1;i++)
    {
        for(int j=i+1;j<strlen(napis);j++)
        {
            if(napis[i]==napis[j])
            {
                for(int k=j;k<strlen(napis)-1;k++)
                {
                    napis[k]=napis[k+1];
                }
                napis[strlen(napis)-1]='\0';
                j=i+1;
            }
        }
    }
}

int main()
{
    char wejscie[11];
    cin >> wejscie;
    cin.ignore();
    usun_powtorki(wejscie);
    usun_powtorki(wejscie);
    int *zlicz=new int[strlen(wejscie)];
    for(unsigned i=0;i<strlen(wejscie);i++)
    {
        zlicz[i]=0;
    }
    char napis[101];
    short int t;
    cin >> t;
    cin.ignore();
    while(t--)
    {
        cin.get(napis,101);
        cin.ignore();
        for(unsigned i=0;i<strlen(wejscie);i++)
        {

            zlicz[i]=szukaj(napis,wejscie[i]);
            cout << wejscie[i] << ": " << zlicz[i] << endl;
        }
    }
    delete[]zlicz;
    return 0;
}

Edit. Dodalem funkcje usuwajaca powtorki ;p Nie chce mi sie jej poprawiac bo juz pozno xD, wiec wywolalem ja 2 razy i dobrze usuwa powtarzajace sie znaki w wejsciu. Teraz powinno byc ok.

1 użytkowników online, w tym zalogowanych: 0, gości: 1