Te dwie funkcje powinny wyglądać inaczej.
Źle:
int sprawdzDlugosc(int dl[])
{
for (int i = 0; i < 4; i++)
if (dl[i] != dl[i + 1]) return 0;
return 1;
}
int sprawdzZnak(char znak, string s)
{
for(int i=0; i<s.size(); i++)
if(s[i]==znak) return 1;
return 0;
}
Dobrze (a w każdym razie lepiej, proszę się nie czepiać o brak wektorów):
bool check_all_strings_equal_size(string tab[], size_t size) {
for (size_t i = 0; i + 1 < size; ++i) {
if (tab[i].size() != tab[i+1].size()) {
return false;
}
}
return true;
}
bool string_contains_char(string& s, char c) {
return s.find(c) != string::npos;
}
Wtedy tablica dl
wylatuje, i można uprościć maina (który notabene powinien zwracać int
a).
Oraz dodatkowo, tablica string s[6]
powinna być tak naprawdę tablicą string s[5];
(nauczyciel nie umie liczyć). Tablica char znak[100];
też nigdzie nie jest używana, można ją pominąć. Tablicę string s[5];
Można przenieść do środka pętli, zgodnie z maksymą, że deklaracja zmiennych powinna być jak najbliżej miejsca użycia (a nie ma potrzeby, żeby różne obroty tej samej pętli używały tych samych stringów).
Dodatkowo program jest błędny, bo w każdym obejściu pętli dwukrotnie czyta linijkę z pliku, a więc połowę linijek pomija w przypadku podpunktu a, i drugą połowę z nich pomija w przypadku podpunktu b.
Posprzątany main
:
int main()
{
ifstream fin("anagram.txt");
ofstream fout1("odp_4a.txt");
ofstream fout2("odp_4b.txt");
while (!fin.eof()) {
const size_t tab_size = 5;
string s[tab_size];
for (int i = 0; i < tab_size; i++) {
fin >> s[i];
}
if (check_all_strings_equal_size(s, tab_size)) {
for (int i = 0; i < tab_size; i++) {
fout1 << s[i] << " ";
}
fout1 << endl;
if (sprawdzAnagram(s)) {
for (int i = 0; i < tab_size; i++) {
fout2 << s[i] << " ";
}
fout2 << endl;
}
}
}
fin.close();
fout1.close();
fout2.close();
return 0;
}
A co do ostatniej funkcji, trochę żałosna jest, kwadratowa złożoność. No ale niech będzie.
Sama funkcja w sobie jest błędna, bo ignoruje opcję, że znaki w stringach mogą się powtarzać, i wtedy może zgłaszać błędne wyniki. Np. według niej, anagramami są "aaabb"
oraz "babbb"
, ale ciężko powiedzieć czy tak miało być, czy tak przypadkiem wyszło.
Zmienna i
nie jest używana w ogóle. W efekcie, funkcja działa kilka razy dłużej, robiąc dokładnie to samo. Równie dobrze można pominąć ją. Innymi słowy, to jest równoważne (o ile s[0].size() > 0
):
int sprawdzAnagram(string s[])
{
for(int j=1; j<5; j++)
for(int k=0; k<s[j].size(); k++)
if(!sprawdzZnak(s[j][k],s[0])) return 0;
return 1;
}
No ale chyba stać nas na trochę więcej niż taką drobną poprawkę.
Trochę przepisana wersja. Wprowadzam funkcję, która sprawdza, czy pewne dwa stringi są anagramem.
bool is_anagram(string& s1, string& s2) {
for (size_t k = 0; k < s1.size(); k++) {
// Jeśli się zdaży, że s2 nie zawiera któregoś ze znaków z s1, to nie są anagramem.
if (!string_contains_char(s2, s1[k])) {
return false;
}
}
return true;
}
bool sprawdzAnagram(string s[], size_t size)
{
for(int k = 1; j < size; j++) {
if (!is_anagram(s[0], s[k])) {
return false;
}
}
return true;
}