Refaktoryzacja starego kodu

0

Witam. Ostatnio przeglądam moje starsze programy, który pisałem na SPOJ i znalazłem tę perłę co poniżej. Strasznie mi głupio że taki kod wyszedł spod mojej klawiatury, i czuje że zadanie rozwiązałem metodą buta w drzwiach. Chciałbym prosić o sugestie jak można to zapisać krócej i ładniej. Myślałem o przerobieniu tego na klasy, albo użycie jakiegoś kontenera STL, ale chyba mam z tym za małe doświadczenie, ponieważ nie widzę sposobu jak mógłbym przez to skrócić kod. Program zrobiony na potrzeby zadania: http://pl.spoj.com/problems/JZLICZ/

// Do refaktoryzacji
#include <iostream>
#include <cctype>

using namespace std;

int main()
{
    int lines;
    cin >> lines;
    cin.ignore();
    int letterNumber[52];
    for (int k = 0; k < 52; ++k)
    {
        letterNumber[k]=0;
    }
    for(int j = 0; j < lines; ++j)
    {
        string fraze;
        getline(cin, fraze);
        for(int i = 0; i < fraze.length(); ++i)
        {
            switch (fraze[i])
            {
                case 'a': ++letterNumber[0]; break;
                case 'b': ++letterNumber[1]; break;
                case 'c': ++letterNumber[2]; break;
                case 'd': ++letterNumber[3]; break;
                case 'e': ++letterNumber[4]; break;
                case 'f': ++letterNumber[5]; break;
                case 'g': ++letterNumber[6]; break;
                case 'h': ++letterNumber[7]; break;
                case 'i': ++letterNumber[8]; break;
                case 'j': ++letterNumber[9]; break;
                case 'k': ++letterNumber[10]; break;
                case 'l': ++letterNumber[11]; break;
                case 'm': ++letterNumber[12]; break;
                case 'n': ++letterNumber[13]; break;
                case 'o': ++letterNumber[14]; break;
                case 'p': ++letterNumber[15]; break;
                case 'q': ++letterNumber[16]; break;
                case 'r': ++letterNumber[17]; break;
                case 's': ++letterNumber[18]; break;
                case 't': ++letterNumber[19]; break;
                case 'u': ++letterNumber[20]; break;
                case 'v': ++letterNumber[21]; break;
                case 'w': ++letterNumber[22]; break;
                case 'x': ++letterNumber[23]; break;
                case 'y': ++letterNumber[24]; break;
                case 'z': ++letterNumber[25]; break;

                case 'A': ++letterNumber[26]; break;
                case 'B': ++letterNumber[27]; break;
                case 'C': ++letterNumber[28]; break;
                case 'D': ++letterNumber[29]; break;
                case 'E': ++letterNumber[30]; break;
                case 'F': ++letterNumber[31]; break;
                case 'G': ++letterNumber[32]; break;
                case 'H': ++letterNumber[33]; break;
                case 'I': ++letterNumber[34]; break;
                case 'J': ++letterNumber[35]; break;
                case 'K': ++letterNumber[36]; break;
                case 'L': ++letterNumber[37]; break;
                case 'M': ++letterNumber[38]; break;
                case 'N': ++letterNumber[39]; break;
                case 'O': ++letterNumber[40]; break;
                case 'P': ++letterNumber[41]; break;
                case 'Q': ++letterNumber[42]; break;
                case 'R': ++letterNumber[43]; break;
                case 'S': ++letterNumber[44]; break;
                case 'T': ++letterNumber[45]; break;
                case 'U': ++letterNumber[46]; break;
                case 'V': ++letterNumber[47]; break;
                case 'W': ++letterNumber[48]; break;
                case 'X': ++letterNumber[49]; break;
                case 'Y': ++letterNumber[50]; break;
                case 'Z': ++letterNumber[51]; break;
                default: break;
            }
        }
    }
            if(letterNumber[0] > 0) cout <<"a " << letterNumber[0] << endl;
            if(letterNumber[1] > 0) cout <<"b " << letterNumber[1] << endl;
            if(letterNumber[2] > 0) cout <<"c " << letterNumber[2] << endl;
            if(letterNumber[3] > 0) cout <<"d " << letterNumber[3] << endl;
            if(letterNumber[4] > 0) cout <<"e " << letterNumber[4] << endl;
            if(letterNumber[5] > 0) cout <<"f " << letterNumber[5] << endl;
            if(letterNumber[6] > 0) cout <<"g " << letterNumber[6] << endl;
            if(letterNumber[7] > 0) cout <<"h " << letterNumber[7] << endl;
            if(letterNumber[8] > 0) cout <<"i " << letterNumber[8] << endl;
            if(letterNumber[9] > 0) cout <<"j " << letterNumber[9] << endl;
            if(letterNumber[10] > 0) cout <<"k " << letterNumber[10] << endl;
            if(letterNumber[11] > 0) cout <<"l " << letterNumber[11] << endl;
            if(letterNumber[12] > 0) cout <<"m " << letterNumber[12] << endl;
            if(letterNumber[13] > 0) cout <<"n " << letterNumber[13] << endl;
            if(letterNumber[14] > 0) cout <<"o " << letterNumber[14] << endl;
            if(letterNumber[15] > 0) cout <<"p " << letterNumber[15] << endl;
            if(letterNumber[16] > 0) cout <<"q " << letterNumber[16] << endl;
            if(letterNumber[17] > 0) cout <<"r " << letterNumber[17] << endl;
            if(letterNumber[18] > 0) cout <<"s " << letterNumber[18] << endl;
            if(letterNumber[19] > 0) cout <<"t " << letterNumber[19] << endl;
            if(letterNumber[20] > 0) cout <<"u " << letterNumber[20] << endl;
            if(letterNumber[21] > 0) cout <<"v " << letterNumber[21] << endl;
            if(letterNumber[22] > 0) cout <<"w " << letterNumber[22] << endl;
            if(letterNumber[23] > 0) cout <<"x " << letterNumber[23] << endl;
            if(letterNumber[24] > 0) cout <<"y " << letterNumber[24] << endl;
            if(letterNumber[25] > 0) cout <<"z " << letterNumber[25] << endl;

            if(letterNumber[26] > 0) cout <<"A " << letterNumber[26] << endl;
            if(letterNumber[27] > 0) cout <<"B " << letterNumber[27] << endl;
            if(letterNumber[28] > 0) cout <<"C " << letterNumber[28] << endl;
            if(letterNumber[29] > 0) cout <<"D " << letterNumber[29] << endl;
            if(letterNumber[30] > 0) cout <<"E " << letterNumber[30] << endl;
            if(letterNumber[31] > 0) cout <<"F " << letterNumber[31] << endl;
            if(letterNumber[32] > 0) cout <<"G " << letterNumber[32] << endl;
            if(letterNumber[33] > 0) cout <<"H " << letterNumber[33] << endl;
            if(letterNumber[34] > 0) cout <<"I " << letterNumber[34] << endl;
            if(letterNumber[35] > 0) cout <<"J " << letterNumber[35] << endl;
            if(letterNumber[36] > 0) cout <<"K " << letterNumber[36] << endl;
            if(letterNumber[37] > 0) cout <<"L " << letterNumber[37] << endl;
            if(letterNumber[38] > 0) cout <<"M " << letterNumber[38] << endl;
            if(letterNumber[39] > 0) cout <<"N " << letterNumber[39] << endl;
            if(letterNumber[40] > 0) cout <<"O " << letterNumber[40] << endl;
            if(letterNumber[41] > 0) cout <<"P " << letterNumber[41] << endl;
            if(letterNumber[42] > 0) cout <<"Q " << letterNumber[42] << endl;
            if(letterNumber[43] > 0) cout <<"R " << letterNumber[43] << endl;
            if(letterNumber[44] > 0) cout <<"S " << letterNumber[44] << endl;
            if(letterNumber[45] > 0) cout <<"T " << letterNumber[45] << endl;
            if(letterNumber[46] > 0) cout <<"U " << letterNumber[46] << endl;
            if(letterNumber[47] > 0) cout <<"V " << letterNumber[47] << endl;
            if(letterNumber[48] > 0) cout <<"W " << letterNumber[48] << endl;
            if(letterNumber[49] > 0) cout <<"X " << letterNumber[49] << endl;
            if(letterNumber[50] > 0) cout <<"Y " << letterNumber[50] << endl;
            if(letterNumber[51] > 0) cout <<"Z " << letterNumber[51] << endl;
    return 0;
}

Z góry dziękuję za odpowiedzi.

PS: Na prośbę mogę dodać jakiś alert żeby nie wchodzić, bo brzydki kod.

1

Mi bez użycia kontenerów (sopja rozwiązuję w gołym C) rozwiązanie zajęło (a piszę stosując rozlazłą metodę gdzie każdy nawias mam w nowej linii) 18 linijek. Użyłem po prostu tablicy. Z tym, że dla wygody zrobiłem tablicę 256 (tyle możliwych wartości przyjmie nam char) intów. I zapisywałem na chama jako:

++letterNumber[fraze[i]]

. Potem na koniec w pętelce wypisywanie całej tablicy tylko tych elementów gdzieletterNumber[i] > 0

i gotowe.

Oczywiście można to zaimplementować bardziej oszczędnie pamięciowo. Jednak nie wiem czy warto. W końcu tablica 256 intów nie zajmie tak dużo ;)
3

http://ideone.com/0EujfS

#include <iostream>
#include <cctype>
using namespace std;
 
int main()
  {
   unsigned cnt,lwr[26]={0},upr[26]={0};
   cin>>cnt;
   for(int ch;(ch=getchar())!=EOF;) if(islower(ch)) ++lwr[ch-'a']; else if(isupper(ch)) ++upr[ch-'A'];
   for(unsigned i=0;i<26;++i) if(lwr[i]) cout<<(char)('a'+i)<<' '<<lwr[i]<<endl;
   for(unsigned i=0;i<26;++i) if(upr[i]) cout<<(char)('A'+i)<<' '<<upr[i]<<endl;
   return 0;
  }
2

@kq odpowiem tu, bo w komentarzu będzie brzydko wyglądał kod. Faktycznie spojrzałem w swój archiwalny kod nieco dokładniej. Na koniec mam 2 pętle:

  for (i='a';i<='z';i++)
    if (tab[i] > 0)
      printf("%c %d\n",i,letters[i]);
  for (i='A';i<='Z';i++)
    if (tab[i] > 0)
      printf("%c %d\n",i,letters[i]);

Jednak i tak bardziej elegancko jest tak jak to zrobił wyżej @_13th_Dragon z dwiema tablicami.

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