Kurs podstawy programowania UMCS, zdjęcie laptopa.

Podstawy programowania – Laboratorium 15

Zadanie 1

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

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

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,
};

void convert(int n, char *result) {
    result[0] = '\0';
    for(numerals_t const *curr = numeral_map; curr->integer > 0; curr++) {
        while(n >= curr->integer){
            strcat(result, curr->numeral);
            n -= curr->integer;
        }
    }
}

int main() {
    int n;
    char result[100] = {};
    std::cin >> n;
    convert(n, result);
    std::cout << result << 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 <cstring>

int binaryToDecimal(const char* binaryStr) {
    int decimal = 0;
    int length = std::strlen(binaryStr);
    for (int i = 0; i < length; ++i) if (binaryStr[i] == '1') decimal += 1 << (length - i - 1);
    return decimal;
}

int main() {
    std::cout << binaryToDecimal("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 <cstdio>

void atbashCipher(char* input, char* output) {
    int i = 0, j = 0;
    while (input[i]) {
        if (input[i] >= 'a' && input[i] <= 'z') output[j++] = 'z' - (input[i] - 'a');
        else if (input[i] >= 'A' && input[i] <= 'Z') output[j++] = 'Z' - (input[i] - 'A');
        i++;
    }
    output[j] = '\0';
}

int main() {
    char message[256] = {}, encrypted[256] = {};
    fgets(message, 256, stdin);
    atbashCipher(message, encrypted);
    printf("%s\n", encrypted);
    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 <cstdio>
#include <cstring>

int findWord(const char* text, const char* word) {
    char* pos = strstr((char*)text, word);
    if (pos != nullptr) return pos - text;
    return -1;
}

int main() {
    char text[256] = {}, word[50] = {};

    fgets(text, 256, stdin);
    fgets(word, 50, stdin);
    word[strlen(word) - 1] = '\0';

    int pos = findWord(text, word);
    if (pos != -1) printf("%d\n", pos);
    else printf("Nie znaleziono.");
    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 <cstdio>

int main() {
    FILE* file = NULL;
    if((file = fopen("xor.ppm", "w")) == NULL) {
        perror("Błąd otwierania pliku");
        return 1;
    }
    fprintf(file, "P2 256 256 255\n");
    for (int i = 0; i < 256; ++i) {
        for (int j = 0; j < 256; ++j)
            fprintf(file, "%d ", (i ^ j));
        fprintf(file, "\n");
    }
    fclose(file);
    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 <cstdio>

int main() {
    char color[3];
    const int dimx = 800;
    const int dimy = 800;

    FILE* file = NULL;
    if((file = fopen("xor.ppm", "wb")) == NULL) {
        perror("Błąd otwierania pliku");
        return 1;
    }
    fprintf(file, "P6 %d %d 255\n", dimx, dimy);
    for (int i = 0; i < dimx; ++i) {
        for (int j = 0; j < dimy; ++j) {
            color[0]=i % 255; /* red */
            color[1]=j % 255; /* green */
            color[2]=(i*j) % 255; /* blue */
            fwrite(color, sizeof(char), 3, file);
        }
    }
    fclose(file);
    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 100.

Rozwiązanie:
#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;
}

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 struktuę Contestant w języku C++, która ma trzy pola: napis name i dwie liczby całkowite age oraz ratings. Dodatkowo napisz funkcję add_to_file, która w argumencie przyjmuje nazwę pliku i wskaźnik na Contestant. Funkcja ta powinna zapisać przekazaną instancje struktury 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 struktury Contestant. Napisz program w języku C++, który przetestuje działanie tak zaprojektowanej struktury. Źródło treści zadania.

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

struct Contestant {
    char name[100];
    int age;
    int ratings;
};


void add_to_file(const char* filename, Contestant *obj) {
    FILE* file = fopen(filename, "ab");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }
    fwrite(obj, sizeof(*obj), 1, file); 
    fclose(file);
}
    

void output_highest_rated(const char* filename, Contestant* result) {
    FILE* file = fopen(filename, "rb");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }

    Contestant obj;
    if (fread(&obj, sizeof(obj), 1, file) == 1) {
        *result = obj;
    }

    while (fread(&obj, sizeof(obj), 1, file) == 1) {
        if (obj.ratings > result->ratings) {
            *result = obj;
        }
    }
    fclose(file);
}

int main() {
    Contestant result{}, obj1{"Micheal", 18, 2500}, obj2{"Terry", 21, 3200};
    add_to_file("result.bin", &obj1);
    add_to_file("result.bin", &obj2);
    output_highest_rated("result.bin", &result);
    printf("%s %d %d\n", result.name, result.age, result.ratings);
    return 0;
}
//Version 2.0
#include <cstdio>

struct Contestant {
    char name[100];
    int age;
    int ratings;
};


void add_to_file(const char* filename, Contestant *obj) {
    FILE* file = fopen(filename, "ab");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }
    fprintf(file, "%d %d %s\n", obj->age, obj->ratings, obj->name);
    fclose(file);
}
    

void output_highest_rated(const char* filename, Contestant* result) {
    FILE* file = fopen(filename, "rb");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }

    Contestant obj;
    while (fscanf(file, "%d %d %s", &obj.age, &obj.ratings, obj.name) != EOF)
        if (obj.ratings > result->ratings) *result = obj;
    fclose(file);
}

int main() {
    Contestant result{}, obj1{"Micheal", 18, 2500}, obj2{"Terry", 21, 3200};
    add_to_file("result.bin", &obj1);
    add_to_file("result.bin", &obj2);
    output_highest_rated("result.bin", &result);
    printf("%s %d %d\n", result.name, result.age, result.ratings);
    return 0;
}
//Version 3.0
#include <cstdio>
#include <cstring>
#include <iostream>

struct Contestant {
    char *name = NULL;
    int age;
    int ratings;
};


void add_to_file(const char* filename, Contestant *obj) {
    FILE* file = fopen(filename, "ab");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }
    size_t length = strlen(obj->name);
    fwrite(&length, sizeof(length), 1, file);
    fwrite(&obj->age, sizeof(obj->age), 1, file);
    fwrite(&obj->ratings, sizeof(obj->ratings), 1, file);
    fwrite(obj->name, sizeof(char), length + 1, file);
    fclose(file);
}
    
void read_one_and_parse(FILE *file, Contestant &obj) {
    size_t length = 0;
    fread(&length, sizeof(length), 1, file);
    fread(&obj.age, sizeof(obj.age), 1, file);
    fread(&obj.ratings, sizeof(obj.ratings), 1, file);
    if(obj.name) delete[] obj.name;
    obj.name = new char[length + 1]();
    fread(obj.name, sizeof(char), length + 1, file);
}

void output_highest_rated(const char* filename, Contestant* result) {
    FILE* file = fopen(filename, "rb");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }

    Contestant obj;
    read_one_and_parse(file, obj);
    while(feof(file) == 0) {
        if (obj.ratings > result->ratings) {
            result->age = obj.age;
            result->ratings = obj.ratings;
            if(result->name) delete[] result->name;
            result->name = new char[strlen(obj.name) + 1]();
            strcpy(result->name, obj.name);
        }
        read_one_and_parse(file, obj);
    }
    fclose(file);
}

int main() {
    Contestant result{}, obj1{}, obj2{};
    
    obj1.name = new char[8]();
    strcpy(obj1.name, "Micheal");
    obj1.age = 18;
    obj1.ratings = 2500;
    
    obj2.name = new char[6]();
    strcpy(obj2.name, "Terry");
    obj2.age = 21;
    obj2.ratings = 3200;
    
    //add_to_file("result.bin", &obj1);
    //add_to_file("result.bin", &obj2);
    
    output_highest_rated("result.bin", &result);
    printf("%s %d %d\n", result.name, result.age, result.ratings);
    return 0;
}

Zadanie 10

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

Rozwiązanie:
#include <cstdio>

int main() {
    FILE* file = fopen(__FILE__, "r");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return 1;
    }

    char ch;
    while ((ch = fgetc(file)) != EOF) {
        putchar(ch);
    }

    fclose(file);
    return 0;
}

Zadanie 11

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

Rozwiązanie:
#include <cstdio>

int countWords(const char* str) {
    int count = 0, inWord = 0;
    while (*str != '\0') {
        if (*str == ' ') {
            inWord = 0;
        } else if (inWord == 0) {
            inWord = 1;
            count++;
        }
        str++;
    }
    return count;
}

int main() {
    char text[256];
    fgets(text, 256, stdin);
    printf("%d\n", countWords(text));
    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 <cstdio>
#include <ctime>

void appendCurrentDateTime(const char* filename) {
    FILE* file = fopen(filename, "a");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }
    time_t now = time(nullptr);
    struct tm* local = localtime(&now);

    fprintf(file, "%02d-%02d-%d %02d:%02d:%02d\n",
            local->tm_mday, local->tm_mon + 1, local->tm_year + 1900,
            local->tm_hour, local->tm_min, local->tm_sec);
    fclose(file);
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        printf("Użycie: %s <nazwa_pliku>\n", argv[0]);
        return 1;
    }
    appendCurrentDateTime(argv[1]);
    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 <cstdio>
#include <ctime>

void processDates(const char* filename) {
    FILE* file = fopen(filename, "r");
    if (file == nullptr) {
        perror("Błąd otwierania pliku");
        return;
    }

    char buffer[256];
    while (fgets(buffer, sizeof(buffer), file)) {
        int day, month, year, hour, minute, second;
        sscanf(buffer, "%d-%d-%d %d:%d:%d", &day, &month, &year, &hour, &minute, &second);

        struct tm date = {0};
        date.tm_mday = day;
        date.tm_mon = month - 1;
        date.tm_year = year - 1900;
        date.tm_hour = hour;
        date.tm_min = minute;
        date.tm_sec = second;

        time_t t = mktime(&date);
        t += 15 * 24 * 3600 + 37 * 3600;

        struct tm* newDate = localtime(&t);
        printf("%02d-%02d-%d %02d:%02d:%02d\n",
               newDate->tm_mday, newDate->tm_mon + 1, newDate->tm_year + 1900,
               newDate->tm_hour, newDate->tm_min, newDate->tm_sec);
    }

    fclose(file);
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        printf("Użycie: %s <nazwa_pliku>\n", argv[0]);
        return 1;
    }
    processDates(argv[1]);
    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 <cstdio>
#include <cstring>

void findWordsWithSubstring(const char* filename, const char* substring) {
    char word[256];
    FILE* file = NULL;
    if ((file = fopen(filename, "r")) == NULL) {
        perror("Błąd otwierania pliku");
        return;
    }
    while (fscanf(file, "%255s", word) != EOF) if (strstr(word, substring) != nullptr)  printf("%s\n", word);
    fclose(file);
}

int main() {
    const char* filename = "text.txt";
    const char* substring = "any";
    findWordsWithSubstring(filename, substring);
    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 <cstdio>
#include <cstring>
#include <algorithm>

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

void print(const char* taskName, int priority) {
    printf("Zadanie: %s, Priorytet: %d\n", taskName, priority);
}

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

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

int main() {
    int n = 5; 
    Task** tasks = new Task*[n];
    const char* taskNames[] = {"TaskA", "TaskB", "TaskC", "TaskD", "TaskE"};
    int taskPriorities[] = {3, 1, 4, 2, 5};

    for (int i = 0; i < n; ++i) {
        tasks[i] = new Task; 
        strcpy(tasks[i]->name, taskNames[i]); 
        tasks[i]->priority = taskPriorities[i]; 
        tasks[i]->run = print; 
    }

    std::sort(tasks, tasks + n, compareByPriority);
    for (int i = 0; i < n; ++i) tasks[i]->run(tasks[i]->name, tasks[i]->priority);
    
    std::sort(tasks, tasks + n, compareByName);
    for (int i = 0; i < n; ++i) tasks[i]->run(tasks[i]->name, tasks[i]->priority);
    
    for (int i = 0; i < n; ++i) delete tasks[i];
    delete[] tasks;
    return 0;
}

Dodaj komentarz

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