Главная страница
Навигация по странице:

  • Постановка задачи

  • Разработка алгоритма

  • Текст программы

  • Анализ результатов: Рис.1.

  • Лабораторная 7. Отчет по лабораторной работе 7 Обработка символьных строк


    Скачать 63.06 Kb.
    НазваниеОтчет по лабораторной работе 7 Обработка символьных строк
    АнкорЛабораторная 7
    Дата10.04.2023
    Размер63.06 Kb.
    Формат файлаdocx
    Имя файлаЛабораторная 7.docx
    ТипОтчет
    #1052167

    Московский государственный технический

    университет им. Н.Э. Баумана
    Факультет

    Кафедра

    Курс
    Отчет по лабораторной работе №7

    «Обработка символьных строк»

    Вариант №4


    Выполнил:




    Проверил:

    студент группы:




    преподаватель каф. ИУ5










    Подпись и дата:





    Подпись и дата:

    Москва, г.

    Постановка задачи:

    Провести кодирование и декодирование текста (массива символов) при помощи кода Цезаря с переменным сдвигом по таблице ASCII-кодов. Величина сдвига для каждой позиции в исходном тексте - сумма (по модулю 128) кодов символов слова кодового блокнота, стоящего в блокноте на той же позиции. Если кодовый блокнот имеет слов меньше, чем количество символов в исходном тексте, то по исчерпании слов в нём перейти к первому слову и продолжить.

    Исследовать повторяемость символов в закодированном тексте (сколько каких кодов одного и того же исходного символа получено) в зависимости от кодового блокнота и длины исходного текста. Результаты исследования представить в виде таблицы (продумать формат таблицы самостоятельно). В таблице отобразить 5 неповторяющихся символов, выбранных случайным образом. Статистические данные хранить в массиве int stat[128].
    Разработка алгоритма:

    На основе кодового блокнота целесообразно сначала сформировать по заданному правилу целочисленный массив ключей, который затем использовать при кодировании. Эти действия можно оформить в виде отдельной функции keys(). Для кодирования текста можно использовать формулу: x= (y + k)%n

    Где:

    x – закодированный символ;

    y – кодируемый символ;

    k – ключ;

    n – алфавит(в нашем случае 128);

    Так же в случае если получаемый код по ASCII отрицательный, его нужно перевести в положительный.
    FILE *dir, *dir1, *dir3, *dir4 – файлы key.txt, source.txt, encoded.txt, decoded.txt

    char mass1_codir[1024] – массив, хранящий закодированные символы

    char mass2_decodir[300] – массив, хранящий де-кодированные символы

    int mass_keys[300] – массив ключей

    int i - счетчик

    int mass_dlya_povtora[5] – массив для вывода повторяющихся значений

    char * tk – разбиение исходного текста по пробелам

    char r – промежуточная переменная, копия tk[i]

    int sum – сумма букв в слове

    int j - счетчик

    char m[200] - массив для подсчета повторяющихся значений

    int count – кол-во символов
    Текст программы:

    #define _CRT_SECURE_NO_WARNINGS

    #include "caesar.h"

    #include

    #include

    #include

    #include
    void keys(char* t, int* mass_keys, int* n)// функция для подсчета суммы символов для каждого слова кодового блокнота

    {

    char* tk, r;

    int sum;

    tk = strtok(t, " ");

    while (tk != NULL)

    {

    sum = 0;

    for (int i = 0; i < strlen(tk); i++)

    {

    r = (int)tk[i];

    sum += r;

    }

    mass_keys[n[0]] = sum;

    tk = strtok(NULL, " ");

    n[0] += 1;

    }

    }

    void codirovanie(char* t, char* mass1_codir, int* mass_keys, int* n)// функ. Для кодирования

    {

    char* tk;

    int r;

    tk = strtok(t, " ");

    while (tk != NULL)

    {

    for (int i = 0; i < strlen(tk); i++)

    {

    if (n[2] >= n[0])

    {

    n[2] = 0;

    }

    if (tk[i] == '\n')

    {

    mass1_codir[n[1]] = '`';

    }

    else {

    r = tk[i] + mass_keys[n[2]];

    r = r % 128;

    if (r < 0) { r += 128; }

    mass1_codir[n[1]] = r;

    n[2] += 1;

    }

    n[1] += 1;

    }

    if (mass1_codir[n[1] - 1] != '`')

    {

    mass1_codir[n[1]] = '#';

    n[1] += 1;

    }

    tk = strtok(NULL, " ");

    }

    }

    void decodirovanie(char* mass1_codir, int* mass_keys, char* mass2_decodir, int* n)// функ. декодирования

    {

    char r;

    n[2] = 0;

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

    {

    if (mass1_codir[i] == '#')

    {

    mass2_decodir[i] = ' ';

    }

    else if (mass1_codir[i] == '`')

    {

    mass2_decodir[i] = '\n';

    }

    else {

    if (n[2] >= n[0])

    {

    n[2] = 0;

    }

    r = (int)(mass1_codir[i] - mass_keys[n[2]]) % 128;

    if (r < 0) { r += 128; }

    mass2_decodir[i] = r;

    n[2] += 1;

    }

    }

    }

    int Povtor1(int* dlya_povtora1, char* mass1_codir, int count)// функ. Подсчета повторяющихся элементов

    {

    int i, j = 0, t = 0, c;

    char m[200];

    for (i = 0; i < count; i++)

    {

    c = mass1_codir[dlya_povtora1[i]];

    if (memchr(m, (char)mass1_codir[dlya_povtora1[i]], sizeof(m)) == NULL)

    {

    t += 1;

    m[j] = mass1_codir[dlya_povtora1[i]];

    j++;

    }

    }

    return t;

    }

    #define COLUMN_NUMBER 4 // число столбцов таблицы
    struct I_print { // данные для печати результатов интегрирования

    char symbol; // название функции

    int kol_kod; // значение интегральной суммы

    int symbol_v_tex; // точное значение интеграла

    int slov_v_note; // число разбиений области интегрирования при котором достигнута требуемая точность

    };
    void printDividingLine(const char horizontalSybmol, const char connectorSybmol, const int m, const int *wn) {

    putchar(connectorSybmol);

    for (int line_i = 0; line_i < m; line_i++) {

    for (int line_j = 0; line_j < wn[line_i]; line_j++) {

    putchar(horizontalSybmol);

    }

    putchar(connectorSybmol);

    }

    putchar('\n');

    }
    void PrintTabl(struct I_print i_prn[], int k) {

    const char SIDE_SYBMOL = '|';

    const char HORIZONTAL_SYBMOL = '-';

    const char CONNECTOR_SYBMOL = '+';
    int wn[COLUMN_NUMBER] = {12, 18, 17, 15}; // ширина столбцов таблицы

    char *title[COLUMN_NUMBER] = {(char *) "Символ", (char *) "кол-во кодов", (char *) "символов в тексте",

    (char *) "слов в блокноте"};

    int size[COLUMN_NUMBER];

    for (int i = 0; i < COLUMN_NUMBER; i++) {

    size[i] = (int) strlen(title[i]);

    }
    // шапка таблицы
    putchar(SIDE_SYBMOL);

    for (int line_i = 0; line_i < COLUMN_NUMBER; line_i++) {

    int half = (wn[line_i] - size[line_i]) / 2;

    for (int line_j = 0; line_j < half; line_j++) {

    putchar(' ');

    }

    printf("%s", title[line_i]);

    for (int line_j = 0; line_j < half; line_j++) {

    putchar(' ');

    }

    putchar(SIDE_SYBMOL);

    }

    putchar('\n');
    printDividingLine(HORIZONTAL_SYBMOL, CONNECTOR_SYBMOL, COLUMN_NUMBER, wn);
    // заполнение таблицы

    for (int i = 0; i < k; i++) {

    putchar(SIDE_SYBMOL);

    printf("%12c", i_prn[i].symbol);

    putchar(SIDE_SYBMOL);
    char kol_kod[15];

    printf("%18d", i_prn[i].kol_kod);

    putchar(SIDE_SYBMOL);
    char symbol_v_tex[15];

    printf("%17d", i_prn[i].symbol_v_tex);

    putchar(SIDE_SYBMOL);
    printf("%15d", i_prn[i].slov_v_note);

    putchar(SIDE_SYBMOL);

    putchar('\n');

    }

    }

    int main() {

    setlocale(LC_ALL, "Russian");

    FILE *dir, *dir1, *dir3, *dir4;

    char t[200], mass1_codir[1024], mass2_decodir[300];

    int mass_keys[300], i, mass_dlya_povtora[5] = {0, 0, 0, 0, 0}, l[5], n[3] = {0, 0, 0};

    dir = fopen("key.txt", "r");

    dir1 = fopen("source.txt", "r");

    dir3= fopen("encoded.txt", "w");

    dir4= fopen("decoded.txt", "w");

    printf("содержимое key.txt:\n");

    while (!feof(dir))

    {

    fgets(t, 199, dir);

    printf("%s", t);

    keys(t, mass_keys, n);

    }

    printf("\n\nсодержимое source.txt:\n");

    while (!feof(dir1))

    {

    fgets(t, 199, dir1);

    printf("%s", t);

    codirovanie(t, mass1_codir, mass_keys, n);

    }

    printf("\n\nсодержимое encoded.txt:\n");

    for (i = 3; i < n[1]; i++)

    {

    if (mass1_codir[i] == '#')

    {

    fprintf(dir3, "%c", ' ');

    printf("%c", ' ');

    }

    else if (mass1_codir[i] == '`')

    {

    fprintf(dir3, "%c", '\n');

    printf("%c", '\n');

    }

    else

    {

    printf("%c", mass1_codir[i]);

    fprintf(dir3, "%c", mass1_codir[i]);

    }

    }

    decodirovanie(mass1_codir, mass_keys, mass2_decodir, n);

    printf("\n\nсодержимое decoded.txt:\n");

    for (i = 3; i < n[1]; i++)

    {

    fprintf(dir4, "%c", mass2_decodir[i]);

    printf("%c", mass2_decodir[i]);

    }

    printf("\n\n");

    i = 0;

    // нахождение 5 случайных символов

    char r;

    while (i < 5)

    {

    r = (char)mass2_decodir[3+rand() % (n[1] - 3+1)];

    if (r != ' ' && memchr(mass_dlya_povtora, r, sizeof(mass_dlya_povtora)) == NULL && r != '\n' )

    {

    mass_dlya_povtora[i] = (int)r;

    i++;

    }

    }

    // кол-во кодов

    int count, dlya_povtora1[200], mass_count[5];

    for (int j = 0; j < 5; j++) {

    count = 0;

    for (i = 0; i < n[1]; i++) {

    if (mass_dlya_povtora[j] == mass2_decodir[i]) {

    dlya_povtora1[count] = i;

    count++;

    }

    }

    mass_count[j] = count;

    //printf(" %c", mass_dlya_povtora[j]);

    l[j] = Povtor1(dlya_povtora1, mass1_codir, count);

    //printf(" %d", l[j]);

    }

    fclose(dir);

    fclose(dir1);

    fclose(dir3);

    fclose(dir4);

    //значения для таблицы

    struct I_print struc;

    struct I_print f_Rect[5];

    for (i = 0; i < 5; i++) {

    struc.symbol = mass_dlya_povtora[i];

    struc.kol_kod = l[i];

    struc.symbol_v_tex = mass_count[i];

    struc.slov_v_note = n[0];

    f_Rect[i] = struc;
    }

    PrintTabl(f_Rect, 5);

    }
    Анализ результатов:


    Рис.1. Пример работы программы

    Источники:

    1. Язык программирования С [2015] Брайан У. Керниган, Деннис М. Ритчи


    написать администратору сайта