To zadanie miało błąd w pliku, lecz na potrzeby ćwiczeń starałem się naprawić ten problem, a mianowicie każda linijka w pliku składała się z zakodowanego słowa oraz klucza do odszyfrowania go, niektóre z tych linijek nie miały klucza w tym miejscu powinno być 0, lecz jest tam spacja.
Wiem, że powinienem użyć metody "strtok", ale zważywszy na to, że na egzaminie maturalnym nie mamy dostępu do internetu, a zapamiętywanie kolejnych fukcji na siłe nie jest dobre postanowiłem plik "Dane_6_2.txt" podzielić w MS Access, dzięki temu mogłem zastosować znane wszystkim "std::getline". Przedstawiam moje rozwiązanie może się komuś przyda na przyszłość, albo teraz klika tygodni przed maturą.
Zadanie 6.1: https://forum.pasja-informatyki.pl/343013/matura-maj-2016-zadanie-6-1-rozwiazanie
Treść zadania:
W pliku dane_6_2.txt zapisano 3 000 szyfrogramów i odpowiadające im klucze
szyfrujące. W każdym wierszu znajduje się jeden szyfrogram (zaszyfrowane słowo)
i po pojedynczym znaku odstępu odpowiadający mu klucz (maksymalnie czterocyfrowa
liczba).
Fragment pliku dane_6_2.txt:
BCYKUNCM 1718
YFOGNSKGYW 7580
WARDA 9334
Napisz program, który odszyfruje słowa zaszyfrowane podanymi kluczami. Wynik zapisz
w pliku wyniki_6_2.txt: każde odszyfrowane słowo w osobnym wierszu, w porządku
odpowiadającym kolejności szyfrogramów z pliku z danymi.
Uwaga:
Dla pierwszego szyfrogramu z pliku dane_6_2.txt (BCYKUNCM) wynikiem jest słowo
ZAWISLAK.
Arkusz:
https://cke.gov.pl/images/_EGZAMIN_MATURALNY_OD_2015/Arkusze_egzaminacyjne/2016/formula_od_2015/MIN-R2_1P-162.pdf
Pliki:
https://www.cke.edu.pl/images/_EGZAMIN_MATURALNY_OD_2015/Arkusze_egzaminacyjne/2016/formula_od_2015/Dane_PR2.zip
Rozwiązanie:
#include <iostream>
#include <fstream> //biblioteka obsługi plików
#include <string>
#include <vector> //vektor ze standardu 11 coś jak dynamiczna tablica
#include <stdlib.h> //fukcja atoi
using namespace std;
char alfabet[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; // tablica znaków alfabetu
ifstream plik; //klasa pliku
string decryption(string in, int k) // fuckja zmieniająca zahasowane słowa na normalne
{
string deHashedString; // zmienna pomocnicza
for(int i = 0; in.length() >= i; i++) // petla wykonywujaca sie dla każdej literki
{
int j = -1; // zmienna pomocnicza ala iterator
while(in[i] != alfabet[j]) // pętla w której badamy, którą literką z kolei jest nasza badana litera
{
j++; // jeśli warunek nie jest spełniony dodaje sie iterator oznaczający pozycje litery np liera "A" = 0
}
if(j != -1){ // sprawdzanie aby dla liczny -1 nie wykonała się dalsza część funckji
int pointer = j - k%sizeof(alfabet); // ustalamy która liczbą w alfabecie była liczba wcześniej po wpisaniu kodu
//modulo k oznacza tyle, że gdy klucz będzie większy niż 25 (ilość liter w alfabecie) zacznie liczenie od 0
if(pointer < 0) // jeżeli nasza liczba jest na - oznacza to że zaczyna od końca alfabet (-1 oznacza 24)
{
deHashedString += alfabet[pointer+sizeof(alfabet)]; // dodawanie znaku do stringa gdy liczba jest < 0 dodajemy
//dlugość tablicy znaków alfabetu otrzymujemy w ten sposób cofniecie się liczby do końca tablicy
}
else
{
deHashedString += alfabet[pointer]; // wypisuje normalną liczbę
}
}
}
return deHashedString; // zwraca stworzonego stringa
}
std::vector<std::string> getWords(string dir) // funkcja zwracająca vektor słow z danego pliku standard 11
{
ifstream file; // zmienna wczytująca plik
std::vector<std::string> lines; // vektor stringów
file.open(dir); // otwiranie pliku
if(file.good()) // sprawdzenie czy plik został wczytany
{
string currLine; // zmienna pomoicnicza
while(std::getline(file,currLine)) // fukcja pobierająca każdą linijkę pliku
{
lines.push_back(currLine); // dodawanie do końca vektora naszej wartości
}
}
file.close(); // zamykamy źródło pliku
return lines; // zwracamy vektor słow
}
std::vector<int> stringToInt(std::vector<std::string> strings) // fukcja zamieniająca stringi na inta
{
std::vector<int> ints; // vektor pomocniczy typu int
for(string get: strings) // petla wykonywująca się dla każdego elementu w vektorze
{
ints.push_back(atoi(get.c_str())); // dodawanie na koniec vektora naszej nowej przekonwertowanej za pomocą fukcji atoi warości
// ważne, aby strina zamienić na tablicę "charów", za to operacje odpowiedzialna jest metoda "c_str()"
}
return ints; // zwraca vektor typu int z przekonwertowanymi znakami
}
int main()
{
std::vector<std::string> words = getWords("Words.txt"); // wczytywanie za pomocą funkcji słow
std::vector<int> keys = stringToInt(getWords("Key.txt")); // wczytywanie za pomocą fukcji kluczy oraz przekonwertowanie ich na inty
for (int i = 0; words.size() > i; i++) // petla wykonywująca sie dla każdego słowa w vektorze słów
{
string deHashedString = decryption(words.at(i), keys.at(i)); // towrzenie słowa, które po użyciu klucza staje sie zrozumiałe
cout << deHashedString << endl; // zwaraca do konsoli nowo otrzymane słowo
}
return 0; // kończy program
}