Zliczanie liter

0

Napisałem program który tak jak w temacie zlicza litery(zadanie spoj ;) ) otóż program działa poprawnie lecz przekracza limit czasu :/ wydaje mi się że przekombinowałem troche :) był bym wdzieczny gdyby ktoś zerknął i skrytykował początkującego :) co jest źle i co musiał bym poprawić żeby było lepiej :)

#include<iostream>
#include<string>
using namespace std;
string policz(string zwroc);
string sortuj(string sort);
string zam(string sort);
int main()
{
	int N;
	string zdanie,sumuj;
	
	cin>>N;
	if(N<=150)
	{
		while(N)
		{
			cin.ignore(2,'\n');
			getline(cin,zdanie);
			sumuj+=zdanie;
			zdanie.clear();
			N--;
		}
		
		policz(zam(sortuj(sumuj)));
	}
	cin.ignore();
	cin.get();
}
string sortuj(string sort) 
{
	char zapamietaj;
	string zamien;
	for(unsigned int i=0;i<sort.size();i++)
	{
		if(sort[i]==' ')
		{
			sort.erase(i,1);
			i--;
		}
		else
		{
			for(unsigned int j=0;j<sort.size();j++)
			{
				if(sort[i]<=sort[j])
				{
					zapamietaj = sort[i];
					sort[i] = sort[j];
					sort[j] = zapamietaj;
				}
			}
		}
	}
	
	return sort;
}
string policz(string zwroc) 
{
	int p=0,policz=0;
	signed int i=-1;
	char tab[60];
		
		do
		{
			do
			{
				i++;
				policz++;
			}while(i<zwroc.size() && zwroc[i]==zwroc[i+1]);
			
			tab[p]=zwroc[i];
			cout<<tab[p]<<' '<<policz<<endl;
			policz=0;
			p++;
		}while(i<zwroc.size()-1);
	 
	return zwroc;
}
string zam(string sort)
{
	int dodaj=0;
	string zamien;
	for(unsigned int k=0;k<sort.size();k++)
	{
		if(sort[k]>='a' && sort[k]<='z')
			break;
		dodaj++;
	}
	if(dodaj!=0)
	{
		zamien = sort.substr(dodaj,string::npos);
		zamien+= sort.substr(0,dodaj);
	}
	return zamien;
}
0

Sorry, że 'nie pomogę', ale... wolniej się nie dało? Przecież to jest jedna pętelka + pojedyncza tablica, u Ciebie to ma złożoność n^wpizdu.

0

Kolega z góry chyba zle mnie zrozumiał :) tu jest tresc zadania https://pl.spoj.pl/problems/JZLICZ/

0

kolega dobrze zrozumial. Ty nie zrozumialeś.

Opracuj program ZLI, który:

  • wczyta ze standardowego wejścia tekst do analizy,
  • dla każdej litery obliczy liczbę jej wystąpień w tekście,
  • wypisze wynik na standardowe wyjście.

Input
W pierwszym wierszu N - liczba wierszy tekstu do analizy (N≤150). W każdym z następujących N wierszy ciąg złożony z maksymalnie 200 znaków spośród małych i wielkich liter alfabetu łacińskiego (z´, Z´) oraz spacji.

0' podaja Ci ilosc wierszy, ktora w zasadzie jest nie potrzebna
1' masz ograniczona dlugosc wiersza do 200 znakow. nawet nie potrzebujesz klasy std::string ani dynamicznych tablic
2' masz podpowiedziane, ze wystepuja tylko spacje, duze i male litery łacińskiego. zero unicode, samo czyste ansi, 1b per znak. czyli na statystyke wystarczy Ci mała tablica ok.25 znakow.
3' caly tekst traktujesz całościowo, nie musisz zliczac na nowo miedzy wierszami. jezu, wiec nawet od Ciebie umiejetnosci wyczyszczenia statystyki nie wymagaja.

rozwiazanie tego zadania to dokladnie (zeby pamietac statsy) jedna mala tablica plus (zeby zebrac statsy)jedna mala petla z jedna linijka w srodku, plus (zeby olac liczbe linii)jedna linijka przed petla, plus (zeby wypisac wynik) druga mala petla na koncu programu z jedna linijka w srodku.

w czym masz problem? nawet nie patrze juz na kod ktory wkleiles...

edit: ah.. moze problem w duze/male litery? -> tolower

0

Dzieki quetz :) po ciężkich zmaganiach program działa jak należy (1 ptk więcej :D)

0

Witam, również mam problem z tym zadaniem, jednak mój bardziej polega na tym że nie mogę wczytać wiecej niz jednej linijki tekstu :

#include <string>
#include <iostream>
#include <conio.h>

using namespace std;

void ZliczZnaki(std::string strTekst, char chZnak)
{
        unsigned uIlosc = 0 ;
              for ( unsigned i = 0 ; i <= strTekst.length() - 1 ; ++i)
              {
                    if (strTekst[i] == chZnak)
                         ++uIlosc;
              }
              
  if(uIlosc!=0)cout<<chZnak<<" "<<uIlosc<<endl;
}
int main()
{
    int t,i=0;
    cin>>t;
    string strNapis[t],strSuma;
    for(int i=0;i<t;i++)strNapis[i]="";
    while(t!=0)
    {
            
          cin>>strNapis[i];
          strSuma+=strNapis[i];
          t--;i++;
    }

     
         
//Tablicom znaków przypisujemy wartości literek
         char chSzukanyZnak[25] ;
         for(int i=97;i<=122;i++){chSzukanyZnak[i]=i;}  //małe
         char chSzukanyZnak2[25] ;
         for(int i=65;i<=90;i++){chSzukanyZnak2[i]=i;}  //duże
         
         for(int i=97;i<=122;i++)
         ZliczZnaki(strSuma, chSzukanyZnak[i]);
         for(int i=65;i<=90;i++)
         ZliczZnaki(strSuma, chSzukanyZnak2[i]);

getch();
} 

Program jak gdyby przechodzi tylko raz przez pętle while i wyrzuca mi wynik funkcji ZliczZnaki , zamiast wczytywać kolejne ciągi (dopóki t nie bedzie różne od 0 ) . Próbowałem różnych sposonów z https://pl.spoj.pl/forum/viewtopic.php?f=10&t=1207 ale to dalej to samo

0

Ok wymyśliłem :

#include <string>
#include <iostream>


using namespace std;

void ZliczZnaki(std::string strTekst, char chZnak)
{
        unsigned uIlosc = 0 ;
              for ( unsigned i = 0 ; i <= strTekst.length() - 1 ; ++i)
              {
                    if (strTekst[i] == chZnak)
                         ++uIlosc;
              }
              
  if(uIlosc!=0)cout<<chZnak<<" "<<uIlosc<<endl;
}
int main()
{
    int t,i=0;
    cin>>t;
    string strNapis,strSuma;
    char cNapis[200];
    
    while(t!=-1)
    {
         getline(cin,strNapis);
         strSuma+=strNapis;
         t--;
         
          
          
    }

     

         char chSzukanyZnak[25] ;
         for(int i=97;i<=122;i++){chSzukanyZnak[i]=i;}  
         char chSzukanyZnak2[25] ;
         for(int i=65;i<=90;i++){chSzukanyZnak2[i]=i;}  
         
         for(int i=97;i<=122;i++)
         ZliczZnaki(strSuma, chSzukanyZnak[i]);
         for(int i=65;i<=90;i++)
         ZliczZnaki(strSuma, chSzukanyZnak2[i]);

return 0;
} 

Ale nie mieszcze się w czasie. Co moge zrobic żeby to zmienic ?

1

Pomyśleć.

0

Wersja STL poniżej. Na spoju nie pójdzie, bo korzystają z ponad czteroletniego GCC.

#include <iostream>
#include <string>
#include <map>
#include <cctype>

using namespace std;

int main()
{
	int dummy;
	cin >> dummy;
	
	auto comparer = [&dummy](char first, char second)
	{
		if(islower(first) && !islower(second)) return true;
		if(isupper(first) && !isupper(second)) return false;
		return first < second;
	};

	map<char, int, decltype(comparer)> letters(comparer);

	string line;
	while(getline(cin, line))
		for(char letter : line) if(isalpha(letter)) letters[letter]++;

	for(auto pair : letters) cout << pair.first << " " << pair.second << "\n";

	return 0;
}

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