Matura z informatyki 2016 - zadanie 6.3

0

Cześć,
Właśnie przygotowuję się do matury z informatyki i mam problem z zadaniem z ostatniej matury. Oto treść:
user image

W załączniku link do danych potrzebnych do zadania.

Mój kod wygląda tak:

 
#include <iostream>
#include <string>
#include <fstream>

using namespace std;
string szyfr( string txt, int klucz )
{
    int liczba = txt.length();
    klucz = klucz % 26;
    for( int i = 0; i < liczba; i++ )
    {
        if( klucz + txt[ i ] > 90 )
             txt[ i ] =( txt[ i ] + klucz - 90 ) + 64;
        else if( klucz + txt[ i ] < 65 )
             txt[ i ] = 91 -( 65 -( klucz + txt[ i ] ) );
        else
             txt[ i ] = txt[ i ] + klucz;

    }
    return txt;
}
int main()
{
    ifstream inFile;
    inFile.open("dane_6_3.txt");
    ofstream outFile, outFile1;
    outFile.open("wyniki_6_3.txt");

    string tekst;
    string tekstSz;
    int j=1;
    while(inFile.good())
    {
        inFile>>tekst>>tekstSz;

        for (int i=1;i<=26;i++){
            if(tekstSz==szyfr(tekst,i)){
                cout<<j++<<" "<<tekst<<" "<<i<<endl;
                outFile<<" "<<tekst<<endl;
            }
        }
    }

    return 0;
}

Problem polega na tym, że program zwraca mi nazwiska, które zostały zakodowane prawidłowo. Niestety nie mam pomysłu, jak spowodować, by wyświetlały się nazwiska niepoprawnie zakodowane (8 nazwisk, które mój program pomija).
Będę bardzo wdzięczna za pomoc.

Dzięki :-)

4

Proponuje napisać program samodzielnie i wtedy będziesz wiedział co i gdzie się dzieje. Bo tutaj wystarczy odwrócić jeden warunek.

0

Dzięki za odpowiedź.
Tak się składa, że program pisałam sama, ale kombinuję na różne sposoby i nie udaje mi się "odwrócić" wyników wyszukiwania.
Zmiana warunku przy:

 if(tekstSz==szyfr(tekst,i))

na np:
if(tekstSz!=szyfr(tekst,i))
nic nie daje, bo wtedy wyrzuca mi wszystkie przypadki, kiedy frazy się nie zgadzają, a jest ich bardzo dużo...
Dlatego zwróciłam się o pomoc na forum.

3

Ano oczywiście że tak, bo wypisujesz od razu a należy wypisać dopiero PO sprawdzeniu WSZYSTKICH możliwych przesunieć. Więc twoje cout<< czy outFile<< powinny się znaleźć już poza pętlą po wszystkich możliwych kluczach, a warunek powinien być tak skonstruowany żeby sprawdzić czy którykolwiek klucz zadziałał/niezadziałał

Póki co jedyny warunek jaki masz to:

if(tekstSz==szyfr(tekst,i))

A on mówi tylko że tekstSz (nie) odpowiada tekst zakodowanemu przez klucz i.

0

To co w tej chwili masz odpowiada mniej więcej temu:

for (int i = 0; i < liczbaPrzypadkow; ++i)
    if (warunekSpelniony())
        robCos();

"Odwrócenie warunku" daje coś takiego:

int i;
for (i = 0; i < liczbaPrzypadkow; ++i)
    if (warunekSpelniony())
        break;
    
if (i == liczbaPrzypadkow)   // warunek nigdy nie był spełniony
    robCos();
0

Wykombinowałam tak:

 
#include <iostream>
#include <string>
#include <fstream>

using namespace std;
string szyfr(string txt, int klucz)
{
    int liczba = txt.length();
    klucz = klucz % 26;
    for (int i = 0; i < liczba; i++) {
        if (klucz + txt[i] > 90)
            txt[i] = (txt[i] + klucz - 90) + 64;
        else if (klucz + txt[i] < 65)
            txt[i] = 91 - (65 - (klucz + txt[i]));
        else
            txt[i] = txt[i] + klucz;
    }
    return txt;
}
int main()
{
    ifstream inFile;
    inFile.open("dane_6_3.txt");
    ofstream outFile, outFile1;
    outFile.open("wyniki_6_3.txt");

    string tekst;
    string tekstSz;

    int licznik = 0;
    while (inFile.good()) {
        inFile >> tekst >> tekstSz;

        for (int i = 1; i <= 26; i++) {
            if (tekstSz == szyfr(tekst, i)) {
                licznik++;
            }
        }
        if (licznik == 0) {
            cout << tekst << endl;
            outFile << tekst << endl;
        }
        licznik = 0;
    }

    return 0;
}

i otrzymuję poprawne wyniki. Czy Waszym zdaniem coś wymaga poprawienia, jeśli przyjmie się mój tok rozumowania? :-)

0

Generalnie nie trzeba tam licznika, wystarczyłby boolean. Dodatkowo pętle można przerwać jeśli tylko ten boolean będzie "true", bo przecież nie ma sensu sprawdzać dalej. Jeśli chodzi o resztę kodu to magiczne liczby są slabe. Czemu piszesz 65 zamiast 'A'? Samo "szyfrowanie" cezarem też można zrobić trochę wygodniej używając operatora reszty z dzielenia.

0

Zastanawia mnie, skąd wiadomo, że to jest akurat szyfr Cezara, a nie jakiś dowolny inny. W przedstawionej treści zadania nie jest to jednoznacznie zaznaczone. Może to jest tylko fragment większego zadania albo rodzaju szyfru trzeba się domyślić?

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