Kurs podstawy programowania UMCS, zdjęcie laptopa.

PP – Laboratorium 15

Zadanie 1

Napisz program w języku C++, który przekształci liczby arabskie na liczby rzymskie.

Rozwiązanie:
#include <iostream>
#include <string>

struct numerals_t{
    int integer;
    char const* numeral;
};

numerals_t const numeral_map[] = {
    1000, "M",
    900, "CM",
    500, "D",
    400, "CD",
    100, "C",
    90, "XC",
    50, "L",
    40, "XL",
    10, "X",
    9, "IX",
    5, "V",
    4, "IV",
    1, "I",
    0, NULL,
};

std::string convert(int n) {
    std::string result;
    for(numerals_t const *curr = numeral_map; curr->integer > 0; curr++) {
        while(n >= curr->integer){
            result += curr->numeral;
            n -= curr->integer;
        }
    }
    return result;
}

int main() {
    int n;
    std::cin >> n;
    std::cout << convert(n) << std::endl;
    return 0;
}

Zadanie 2

Napisz program w języku C++, który konwertuje zapis binarny liczby reprezentowany przez napis na jej dziesiętny odpowiednik.

Rozwiązanie:
#include <iostream>
#include <string>
#include <cmath>

int convert(std::string input ) {
    int sum = 0;
    for(size_t i = 0; i < input.size(); ++i) {
        char c = input[i];
        if(c == '1'){
            sum += (int)pow(2, input.size() - 1 - i);
        } else if(c != '0') {return 0;}
    }
    return sum;
}

int main() {
    std::cout << convert("1010101") << std::endl;
    return 0;
}

Zadanie 3

Napisz program w języku C++, który będzie w stanie zaszyfrować i odszyfrować wiadomość szyfrem AtBash. Szyfr AtBash jest to prosty monoalfabetyczny szyfr podstawieniowy pochodzenia hebrajskiego, którego działanie polega na zamianie litery leżącej w odległości X od początku alfabetu na literę leżącą w odległości X od jego końca. Szyfrowanie powinno usuwać wszystkie białe znaki w tekście.

Rozwiązanie:
#include <iostream>
#include <string>

std::string atbash(const std::string& s) {
    std::string r;
    for(size_t i = 0; i < s.size(); ++i) {
        if(isalpha(s[i]))
            r.push_back('a' + 'z' - tolower(s[i]));
        else if(isdigit(s[i]))
            r.push_back(s[i]);
    }
    return r;
}

int main() {
    std::string msg = atbash("Emil test.");
    std::cout << msg << std::endl << atbash(msg) << std::endl;
    return 0;
}

Zadanie 4

Napisz program w języku C++, który w tekście przekazanym przez użytkownika znajdzie dowolne słowo i zwróci pozycję jego wystąpienia.

Rozwiązanie:
#include <iostream>
#include <string>

int main() {
    std::string text;
    getline(std::cin, text);
    int pos = text.find("dowolne");
    std::cout << (pos >= 0 ? std::to_string(pos) : "Nie znaleziono.") << std::endl;
    return 0;
}

Zadanie 5

Napisz program w języku C++, który stworzy rastrowy plik graficzny w skali szarości. Plik powinien być zapisany w formacie PPM (Wikipedia).

Rozwiązanie:
#include <fstream>

int main() {
	std::ofstream file;
	file.open("xor.ppm");
	file << "P2 256 256 255\n";
	for (int i = 0; i < 256; ++i)
		for (int j = 0; j < 256; ++j)
			file << (i ^ j) << ' ';
	file.close();
	return 0;
}

Zadanie 6

Napisz program w języku C++, który stworzy rastrowy plik graficzny. Plik powinien być zapisany w formacie PPM (Wikipedia).

Rozwiązanie:
#include <fstream>

int main() {
    const int dimx = 800;
    const int dimy = 800;

    std::ofstream file;
    file.open("xor.ppm", std::fstream::binary);
    file << "P6 " << dimx << " " << dimy << " 255\n";
    for(int j = 0; j < dimy; ++j){
        for(int i = 0; i < dimx; ++i){
            char color[3];
            color[0]=i % 255; /* red */
            color[1]=j % 255; /* green */
            color[2]=(i*j) % 255; /* blue */
            file.write(color, 3);
        }
    }

    file.close();
    return 0;
}

Zadanie 7

Napisz program w języku C++, który odczyta rastrowy plik graficzny stworzony w poprzednim zadaniu i rozjaśni go o 10.

Rozwiązanie:
//Version 1.0
#include <cstdio>

typedef unsigned char uchar;

char f(char value, char mod) {
    return (uchar)value > (255 - (uchar)mod) ? 255 : (uchar)value + (uchar)mod;
}

int main() {
    fpos_t pos;
    int dimx, dimy;
    char brightness = 100;

    FILE * fp = fopen("xor.ppm", "r+b");
    fscanf(fp, "P6 %d %d\n255\n", &dimx, &dimy);
    fgetpos(fp, &pos);
    char *buff = new char[dimx * dimy * 3];
    fread(buff, 3 * dimx, dimy, fp);

    for(int j = 0; j < dimy *dimx * 3; ++j) 
        buff[j] = f(buff[j], brightness);
    fsetpos(fp, &pos);
    fwrite(buff, 3 * dimx, dimy, fp);
    fclose(fp);

    return 0;
}
//Version 2.0
#include <fstream>
#include <string>
#include <sstream>
#include <iostream>

typedef unsigned char uchar;

char f(char value, char mod) {
    return (uchar)value > (255 - (uchar)mod) ? 255 : (uchar)value + (uchar)mod;
}

int main() {
    int dimx, dimy, bpp;
    char brightness = 100;
    std::string line, ss;

    std::fstream file;
    file.open("xor.ppm", std::fstream::in | std::fstream::out | std::fstream::binary);
    
    getline(file, line);
    std::istringstream tmp(line);
    tmp >> ss >> dimx >> dimy >> bpp;
    size_t pos = file.tellg();

    char *buff = new char[dimx * dimy * 3];
    file.read(buff, 3 * dimx * dimy);
    for(int j = 0; j < dimy *dimx * 3; ++j) 
        buff[j] = f(buff[j], brightness);


    file.seekp(pos, std::fstream::beg);
    file.write(buff, 3 * dimx * dimy);
    file.close();
    return 0;
}

Zadanie 8

Napisz program w języku C++, który otworzy plik zawierający dane o średnich ocenach każdego ze studentów I roku. Dane są sformatowane w następujący sposób:
Imię Śr., Imię Śr., …, Imię Śr.,. Program powinien obliczyć średnią ocen całego rocznika i ją wyświetlić. (Imię – maksymalnie 25 elementowe słowo, Śr. – jest liczbą rzeczywistą z dokładnością do dwóch miejsc po przecinku).
Przykład:
Anna 3.4, Jerzy 3.3, Emil 2.2, Bogdan 5,

Rozwiązanie:
#include <cstdio>

int main() {
    float avg = 0.f;
    int n = 0;
    char buffer[25];
    const char *filename = "result.txt";
    FILE *in;

    if ((in = fopen(filename, "r+t")) == NULL) {
        perror("Blad!");
        return 1;
    } else {
        while (feof(in) == 0) {
            float temp;
            fscanf(in, "%s %f,", buffer, &temp);
            avg += temp;
            n++;
        }
        fclose(in);
    }
    printf("%f\n", avg / n);

    return 0;
}

Zadanie 9

Zaprojektuj klasę Contestant w języku C++, która ma trzy pola: napis name i dwie liczby całkowite age oraz ratings. Dodatkowo klasa powinna posiadać metodę add_to_file, która w argumencie przyjmuje nazwę pliku. Metoda ta powinna zapisać instancje klasy do pliku, o nazwie przekazanej w argumencie. Ponadto zaimplementuj funkcję output_highest_rated, która w argumencie przyjmuje nazwę pliku. Funkcja output_highest_rated powinna w pliku, o nazwie przekazanej w argumencie, znaleźć uczestnika o największej ocenie i zwrócić odpowiedni obiekt klasy Contestant. Napisz program w języku C++, który przetestuje działanie tak zaprojektowanej klasy. Źródło treści zadania.

Rozwiązanie:
//Version 1.0
#include <iostream>
#include <fstream>
#include <cstring>

class Contestant {
public:
    char name[100];
    int age, ratings;
    void add_to_file(const char*);
    Contestant() {
    	this->name[0] = 0;
        this->age = 0;
        this->ratings = 0;
    }
    Contestant(const char *name, int age, int ratings) : age(age), ratings(ratings) {
    	strcpy(this->name, name);
    }
};

void Contestant::add_to_file(const char * filename) {
    std::ofstream file(filename, std::fstream::out | std::fstream::app);
    file.write((char*)this, sizeof(*this));
    file.close();
}

void output_highest_rated(const char* filename, Contestant *result) {
    std::ifstream file(filename, std::fstream::in);
    Contestant obj;

    file.read((char *)&obj, sizeof(obj));
    while(!file.eof()) {
        if(obj.ratings > result->ratings) {
            result->age = obj.age;
            result->ratings = obj.ratings;
            strcpy(result->name, obj.name);
        } file.read((char *)&obj, sizeof(obj));
    }
}

int main() {
    Contestant *obj1 = new Contestant("Micheal", 18, 2500);
    Contestant *obj2 = new Contestant("Terry", 21, 3200);
    obj1->add_to_file("result.bin");
    obj2->add_to_file("result.bin");
    Contestant result;
    output_highest_rated("result.bin", &result);
    std::cout << result.name << std::endl;
    delete obj1;
    delete obj2;
    return 0;
}
//Version 2.0
#include <iostream>
#include <fstream>
#include <string>

class Contestant {
public:
    std::string name;
    int age, ratings;
    void add_to_file(const char*);
    Contestant() {
    	this->name = "";
        this->age = 0;
        this->ratings = 0;
    }
    Contestant(std::string name, int age, int ratings) : name(name), age(age), ratings(ratings) { }
};

void Contestant::add_to_file(const char * filename) {
    std::ofstream file(filename, std::fstream::out | std::fstream::app);
    file << this->name << " " << this->age << " " << this->ratings << "\n";
    file.close();
}

void output_highest_rated(const char* filename, Contestant *result) {
    std::ifstream file(filename, std::fstream::in);
    int age, ratings;
    std::string name;

    file >> name >> age >> ratings;
    while(!file.eof()) {
        if(ratings > result->ratings) {
            result->age = age;
            result->ratings = ratings;
            result->name = name;
        } 
        file >> name >> age >> ratings;
    }
}

int main() {
    Contestant *obj1 = new Contestant("Micheal", 18, 2500);
    Contestant *obj2 = new Contestant("Terry", 21, 3200);
    obj1->add_to_file("result.bin");
    obj2->add_to_file("result.bin");
    Contestant result;
    output_highest_rated("result.bin", &result);
    std::cout << result.name << std::endl;
    delete obj1;
    delete obj2;
    return 0;
}
//Version 3.0
#include <iostream>
#include <fstream>
#include <string>

class Contestant {
public:
    std::string name;
    int age, ratings;
    void add_to_file(const char*);
    Contestant() {
        this->name = "";
        this->age = 0;
        this->ratings = 0;
    }
    Contestant(std::string name, int age, int ratings) : name(name), age(age), ratings(ratings) {}
};

void Contestant::add_to_file(const char * filename) {
    std::ofstream file(filename, std::fstream::out | std::fstream::app);
    size_t tmp_length = this->name.length();
    file.write((char*)&this->age, sizeof(this->age));
    file.write((char*)&this->ratings, sizeof(this->ratings));
    file.write((char*)&tmp_length, sizeof(tmp_length));
    file.write((char*)this->name.c_str(), sizeof(char) * this->name.length());
    file.close();
}


void read_one_and_parse(std::ifstream &file, Contestant &obj) {
    size_t tmp_length = 0;
    file.read((char *)&obj.age, sizeof(obj.age));
    file.read((char *)&obj.ratings, sizeof(obj.ratings));
    file.read((char *)&tmp_length, sizeof(tmp_length));
    
    char *tmp_str = new char[tmp_length + 1]();
    file.read((char *)tmp_str, sizeof(char) * tmp_length);
    obj.name = std::string(tmp_str);
    delete[] tmp_str;
}

void output_highest_rated(const char* filename, Contestant *result) {
    std::ifstream file(filename, std::fstream::in);
    Contestant obj;
    read_one_and_parse(file, obj);

    while(!file.eof()) {
        if(obj.ratings > result->ratings) {
            result->age = obj.age;
            result->ratings = obj.ratings;
            result->name = obj.name;
        } 
        read_one_and_parse(file, obj);
    }
}
int main() {
    Contestant *obj1 = new Contestant("Micheal", 18, 2500);
    Contestant *obj2 = new Contestant("Terry", 21, 3200);
    obj1->add_to_file("result.bin");
    obj2->add_to_file("result.bin");
    Contestant result;
    output_highest_rated("result.bin", &result);
    std::cout << result.name << std::endl;
    delete obj1;
    delete obj2;
    return 0;
}

Zadanie 10

Napisz program w języku C++, który wypisze na ekranie treść swojego kodu źródłowego.

Rozwiązanie:
#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::string filename = "main.cpp";

    std::ifstream file(filename);
    if (!file.is_open()) {
        std::cout << "Nie można otworzyć pliku.\n";
        return 1;
    }

    std::string line;
    while (std::getline(file, line)) std::cout << line << std::endl;
    file.close();

    return 0;
}

Zadanie 11

Napisz program w języku C++, który policzy wszystkie słowa w podanym napisie.

Rozwiązanie:
#include <iostream>
#include <string>
#include <sstream>

unsigned int count_words(const std::string& sentence) {
    std::stringstream ss(sentence);
    std::string word;
    unsigned int result = 0;
    while (ss >> word) ++result;
    return result;
}

int main() {
    std::string sentence = "Testowe zdanie, składające się z wielu słow.";
    std::cout << count_words(sentence) << std::endl;
    return 0;
}

Zadanie 12

W języku C++ wydrukuj na ekranie kilka wylosowanych liczb całkowitych z przedziału 0..1000 w taki sposób, aby zawsze cyfra jedności danej liczby znajdowała się podcyfrą jedności poprzedniej liczby. Wydrukuj te liczby ponownie w postaci szesnastkowej.

Rozwiązanie:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>


int rand_min_max(int min, int max) {
    return min + rand() / (RAND_MAX / (max - min + 1));
}

int main() {
    srand(time(0));

    int min = 0, max = 1000;
    for (int i = 0; i < 10; i++) 
        std::cout << std::setw(4) << std::setfill(' ') << rand_min_max(0, 1000) << "\n";
        
    for (int i = 0; i < 10; i++) 
        std::cout << std::hex << std::setw(4) << std::setfill('0') << rand_min_max(0, 1000) << "\n";

    return 0;
}

Zadanie 13

Napisz program w języku C++, który dopisze na końcu podanego w linii poleceń pliku aktualną datę i czas w formacie DD-MM-YYYY hh:mm:ss.

Rozwiązanie:
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>

std::string get_current_date_time() {
    time_t now = time(0);
    struct tm tstruct;
    char buffer[80];
    tstruct = *localtime(&now);
    strftime(buffer, sizeof(buffer), "%d-%m-%Y %H:%M:%S", &tstruct);
    return buffer;
}

int main(int argc, char *argv[]) {
    std::string filename = argv[1];

    std::fstream f;
    f.open(filename, std::fstream::in | std::fstream::out | std::fstream::app);
    if(!f.good()) return 1;
    f << get_current_date_time() << "\n";
    f.close();

    return 0;
}

Zadanie 14

Napisz program w języku C++, który wczyta z podanego w linii poleceń pliku wszystkie daty i czas (w formacie DD-MM-YYYY hh:mm:ss), doda do każdej daty 15 dni i 37 godzin i wyświetli nową datę/czas w tym samym formacie. Możesz wykorzystać funkcje time(), localtime() i mktime() z biblioteki <ctime>.

Rozwiązanie:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <ctime>
#include <iomanip>

std::string add_days_and_hours(const std::string& dt, int days, int hours) {
    struct std::tm t = {};
    std::istringstream ss(dt);
    ss >> std::get_time(&t, "%d-%m-%Y %H:%M:%S");
    t.tm_mday += days;
    t.tm_hour += hours;
    mktime(&t);

    char buffer[80];
    strftime(buffer, sizeof(buffer), "%d-%m-%Y %H:%M:%S", &t);
    return buffer;
}

int main(int argc, char* argv[]) {
    std::string filename = argv[1];
    std::ifstream file(filename);
    if (!file.is_open()) {
        std::cout << "Nie można otworzyć pliku.\n";
        return 1;
    }

    int days = 15, hours = 37;
    std::string line;
    while (std::getline(file, line)) std::cout << add_days_and_hours(line, days, hours) << std::endl;
    file.close();

    return 0;
}

Zadanie 15

Napisz program w języku C++, który w pliku tekstowym znajdzie wszystkie słowa, które zawierają podciąg liter any. Wypisz te słowa na ekranie.

Rozwiązanie:
#include <iostream>
#include <string>
#include <sstream>

void print_words_with_substring(const std::string& sentence, const std::string& substring) {
    std::stringstream ss(sentence);
    std::string word;
    while (ss >> word)
        if(word.find(substring, 0) != std::string::npos)
            std::cout << word << std::endl;
}

int main() {
    std::string sentence = "Tany test anything, something any.";
    print_words_with_substring(sentence, "any");
    return 0;
}

Zadanie 16

W języku C++ zdefiniuj strukturę vec2d, składającą się z dwóch pól x i y typu zmiennoprzecinkowego, która będzie reprezentowała wektor dwuwymiarowy. Utwórz tablicę automatyczną obiektów tego typu. Z pomocą funkcji z biblioteki <algorithm>:
– wypełnij tę tablicę wektorami, których poszczególne współrzędne spełniają zależność: x jest liczbą pseudolosową z zakresu domkniętego <-1, 1> a y jest liczbą przeciwną do x (std::generate);
– wypisz na ekranie wszystkie elementy tej tablicy (std::for_each);
– posortuj wszystkie wektory w tablicy malejąco względem współrzędnej y (std::sort);
– znajdź wektor o najmniejszej współrzędnej x (std::min_element).

Rozwiązanie:
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>

struct vec2d {
    float x, y;
};

vec2d rand_fill() {
    float x =  -1.f + std::rand() / (RAND_MAX / 2.f);
    return {x, -x};
}

void print(const vec2d& v) {
    std::cout << v.x << " " << v.y << std::endl;
}

bool cmp(const vec2d& v1, const vec2d& v2) {
    return v1.y > v2.y || (v1.y == v2.y && v1.x > v2.x);
}

bool min(const vec2d& v1, const vec2d& v2) {
    return v1.x < v2.x;
}

int main() {
    srand(time(0));
    const unsigned int n = 5;
    vec2d arr[n];
    
    std::generate(arr, arr + n, rand_fill);
    std::for_each(arr, arr + n, print);
    std::cout << std::endl;
    std::sort(arr, arr + n, cmp);
    std::for_each(arr, arr + n, print);
    std::cout << std::endl;
    vec2d* result = std::min_element(arr, arr + n, min);
    std::cout << result->x << " " << result->y << std::endl;

    return 0;
}

Zadanie 17

W języku C++ zdefiniuj strukturę Task, która będzie się składała z pól: (1) nazwa zadania (c-string), (2) priorytet zadania (int), wskaźnik run na funkcję realizującą zadanie – funkcja ma przyjmować w parametrze napis c-string i liczbę typu int i zwracać void. Stwórz pomocniczą funkcję o identycznym nagłówku void print(const char*, int), która wyświetli na ekranie podany w parametrze napis i liczbę. Utwórz dynamiczną n-elementową tablicę wskaźników do obiektów typu Task. Zainicjuj wszystkie elementy tej tablicy, a wskaźnik run ustaw na funkcję print().
Z pomocą funkcji z biblioteki <algorithm>:
– posortuj zadania rosnąco względem priorytetu;
– posortuj zadania malejąco względem nazwy zadania;
– dla każdego obiektu z tablicy za pomocą wskaźnika run wywołaj funkcję, na którą wskazuje.

Rozwiązanie:
#include <iostream>
#include <algorithm>
#include <cstring>

struct Task {
    char name[100];
    int priority;
    void (*run)(char[], int);
};

void print(char name[], int priority) {
    std::cout << name << ", " << priority << std::endl;
}

bool cmp_0(const Task* a, const Task* b) {
    return a->priority < b->priority;
}

bool cmp_1(const Task* a, const Task* b) {
    return -strcmp(a->name, b->name);
}

int main() {
    const int n = 5;
    Task** arr = new Task*[n];

    for (int i = 0; i < n; ++i) {
        arr[i] = new Task;
        strcpy(arr[i]->name, ("Zadanie" + std::to_string(i)).c_str());
        arr[i]->priority = i;
        arr[i]->run = print;
    }

    std::sort(arr, arr + n, cmp_0);
    for(int i = 0; i < n; ++i) arr[i]->run(arr[i]->name, arr[i]->priority);

    std::sort(arr, arr + n, cmp_1);
    for(int i = 0; i < n; ++i) arr[i]->run(arr[i]->name, arr[i]->priority);

    for (int i = 0; i < n; ++i) delete arr[i];
    delete[] arr;

    return 0;
}

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *