Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Рекурсивно обойти поддерево файловой системы, заданное пользователем,



 

 

~simple_grep

 

Рекурсивно обойти поддерево файловой системы, заданное пользователем,

выполнить для каждого найденного файла поиск в нем подстроки, заданной пользователем.

Если подстрока найдена в файле, вывести имя файла на стандартный вывод.

Пример вызова:

./my_grep.exe c:/temp/ abc

Вывод:

c:/temp/1.txt

c:/temp/222/readme

 

Похожим образом работает стандартная утилита grep.

Для получения списка файлов использовать набор функций

opendir, readdir, closedir.

Они упомянуты в заголовочном файле dirent.h

 

Дополнительные условия:

компилятор языка C, стандартная библиотека языка C (использовать

заголовочные файлы stdio.h, stdlib.h, string.h).

Программа должна запускаться из командной строки,

анализировать аргументы командной строки,

выводить результат на стандартный вывод.

 

 

 

~reverse_stdin_search_substr

 

Есть текстовый файл неопределенной длины - стандартный ввод (stdin),

пользователь задает искомую подстроку.

Нужно выбрать все строки из файла, содержащие искомую подстроку,

и вывести их на стандартный вывод (stdout) в обратном порядке, причем

строки перевернуть задом на перед. Пример:

 

искомая подстрока: ab

входной поток:

kdk ldlfu abd d

gdt kjyh gefd

cab ks dghy loo

df fi

выходной поток:

d dba ufldl kdk

ool yhgd sk bac

 

Программа должна запускаться из командной строки и считывать

строки текста пока пользователь не сигнализирует о конце

файла (стандартного ввода) комбинацией Ctrl+D (unix) или

Ctrl+Z (windows). Искомую подстроку задавать как аргумент

командной строки (см. argc, argv).

Необходимо использовать динамическую память для хранения

считываемых строк, так как заранее не известно их количество.

 

 

 

~reverse_stdin_search_numbers

 

Есть текстовый файл неопределенной длины - стандартный ввод (stdin),

пользователь задает натуральное число.

Нужно выбрать все строки из файла, длина которых делится на заданное число

без остатка, и вывести их на стандартный вывод (stdout) в обратном порядке,

причем в каждой строке изменить регистр символов на противоположный. Пример:

 

заданное число: 4

входной поток:

Abc CDE 1278

123 yit

baCD

iopt uUI

выходной поток:

IOPT Uui

BAcd

aBC cde 1278

 

Программа должна запускаться из командной строки и считывать

строки текста пока пользователь не сигнализирует о конце

файла (стандартного ввода) комбинацией Ctrl+D (unix) или

Ctrl+Z (windows). Искомое натуральное число задавать как аргумент

командной строки (см. argc, argv).



Необходимо использовать динамическую память для хранения

считываемых строк, так как заранее не известно их количество.

 

 

 

~sort_stdin

 

Есть текстовый файл неопределенной длины - стандартный ввод (stdin),

нужно отсортировать его строки в лексикографическом порядке

по возрастанию и вывести их на стандартный вывод (stdout).

 

Программа должна запускаться из командной строки и считывать

строки текста пока пользователь не сигнализирует о конце

файла (стандартного ввода) комбинацией Ctrl+D (unix) или

Ctrl+Z (windows).

Необходимо использовать динамическую память для хранения

считываемых строк, так как заранее не известно их количество.

Программа сортирует считанные строки любым алгоритмом сортировки

и выводит их на stdout.

Лексикографическое сравнение строк:

"ABC" < "ABCD", "ABC" = "ABC", "ABC" < "ABD"

Для его выполнения можно воспользоваться функцией strcmp().

 

Дополнительные условия:

компилятор языка C, стандартная библиотека языка C (использовать

только заголовочные файлы stdio.h, stdlib.h, string.h).

Пользователь может перенаправить стандартные ввод и вывод

программы средствами операционной системы.

 

 

~sort_phonebook_hoare

 

Сортировка массива записей (телефонной книги) методом быстрой

сортировки Хоара.

Записи считываются из текстового файла, каждая запись состоит

из двух строк: имя (строка) и телефон (целое число).

Записи отделяются друг от друга пустой строкой.

Сортировать записи по полю "имя" в лексикографическом

порядке (man 3 strcmp) по возрастанию.

Количество записей в файле может быть любым,

нужно сохранять данные в динамически выделенной памяти.

 

Пример вызова:

quick_sort_phone_book.exe input.txt output.txt

 

Пример входного файла:

Vasya

 

Petya

 

Misha

 

Пример выходного файла:

Misha

 

Petya

 

Vasya

 

 

 

~sort_phonebook_tree

 

Сортировка массива записей (телефонной книги) с помощью

двоичного дерева.

Записи считываются из текстового файла, каждая запись состоит

из двух строк: имя (строка) и телефон (целое число).

Записи отделяются друг от друга пустой строкой.

Сортировать записи по полю "телефон" по убыванию.

Количество записей в файле может быть любым,

нужно сохранять данные в динамически выделенной памяти.

 

Сортировка с помощью двоичного дерева состоит из двух

фаз: 1) построение дерева, когда очередной элемент помещается

на свое место в дереве, если он меньше значения в текущем узле,

то поместить в правое поддерево (поскольку сортируем по убыванию),

если больше - в левое поддерево. Если поддерево пустое, то оно

будет создано из нового элемента.

2) обхода дерева "слева направо",

когда рекурсивно выписывается левое поддерево, потом

значение в текущем узле и рекурсивно - правое поддерево.

 

Пример вызова:

tree_sort_phone_book.exe input.txt output.txt

 

Пример входного файла:

Vasya

 

Petya

 

Misha

 

Пример выходного файла:

Petya

 

Misha

 

Vasya

 

 

 

 

~sort_phonebook_funcptr

 

Сортировка массива записей (телефонной книги) методом Пузырька.

Записи считываются из текстового файла, каждая запись состоит

из двух строк: имя (строка) и телефон (целое число).

Записи отделяются друг от друга пустой строкой.

По какому полю сортировать и в каком порядке - задается

пользователем из командной строки, через первый параметр

(возможные значения: NAME - по имени, PHONE - по телефону)

и через второй параметр

(возможные значения: ASC - по возрастанию, DESC - по убыванию).

Третий и четвертый параметры- имена входного и выходного файлов.

Количество записей в файле может быть любым,

нужно сохранять данные в динамически выделенной памяти

(связный список).

Использовать тип "указатель на функцию" для параметризации

функции сортировки.

 

Пример вызова:

bubble_sort_phone_book.exe NAME DESC input.txt output.txt

 

Пример входного файла:

Petya

 

Vasya

 

Misha

 

Пример выходного файла:

Vasya

 

Petya

 

Misha

 

 

 

 

~ext_sort_2way

 

Выполнить сортировку строк в текстовом файле используя метод

внешней сортировки слиянием.

На основе алгоритма двухпутевого слияния можно прийти к рекурсивному

определению сортировки слиянием: исходный массив следует разделить на две половины

(то есть два временных файла), применить к каждой половине алгоритм

сортировки слиянием, а затем с помощью алгоритма

двухпутевого слияния объединить подсписки в один отсортированный массив.

Рекурсивные вызовы завершаются, когда подсписок n-ого уровня,

переданный алгоритму сортировки, будет содержать всего один элемент,

поскольку он, очевидно, уже отсортирован.

 

Пример вызова:

./ext_sort.exe file.txt

 

Дополнительные условия:

компилятор языка C, стандартная библиотека языка C (использовать

только заголовочные файлы stdio.h, stdlib.h, string.h).

Программа должна запускаться из командной строки и получать

параметры (имя файла) из командной

строки (см. параметры функции main(): argc, argv).

 

 

 

~phonebook_editor

 

Интерактивный редактор телефонной книги. Операции добавления просмотра, удаления, загрузки и сохранения.

 

 

 

~hashmap_crc32_chains

 

Реализовать структуру данных хеш-массив на основе хеш-функции CRC32.

Метод разрешения коллизий: связный список.

Размер хеш-таблицы: 4096 элементов.

 

Вычисление CRC32:

http://ru.wikipedia.org/wiki/Циклический_избыточный_код

 

Протестировать хэш путем заполнения его строками текста из произвольного

текстового файла (словарь). Вывести содержимое хеш-массива на стандартный

вывод в читаемом виде (текст) и статистику возникновения коллизий

при заполнении структуры.

 

Программа должна запускаться из командной строки и считывать имя

файла для тестирования со стандартного ввода,

выводить результат на стандартный вывод.

 

 

 

~infix_to_postfix

 

Алгоритм преобразования выражения из инфиксной (привычной) записи

в постфиксную (обратную польскую).

 

Для перевода выражения из инфиксной формы в постфиксную с учетом приоритетов операций и скобок

существует простой алгоритм (Дейкстры). Алгоритм работает со стеком, в котором хранятся знаки операций.

Сначала стек пуст. На вход алгоритму подается последовательность лексем (числа, скобки или знаки операций),

представляющая некоторое арифметическое выражение, записанное в инфиксной форме.

Результатом работы алгоритма является эквивалентное выражение в постфиксной форме.

Вводятся приоритеты операций: открывающая скобка имеет приоритет 0, знаки '+' и '–'

— приоритет 1 и знаки '*' и '/' — приоритет 2.

 

1. Пока не достигнут конец входной последовательности, читать очередную лексему и выполнять с ней следующие операции:

1. если прочитан операнд (число), записать его в выходную последовательность;

2. если прочитана открывающая скобка, положить её в стек;

3. если прочитана закрывающая скобка, вытолкнуть из стека в выходную последовательность

всё до открывающей скобки, при этом сами скобки уничтожаются (удаляются из стека и в ответ не идут);

4. если прочитан знак операции, вытолкнуть из стека в выходную последовательность все операции

с большим либо равным приоритетом, а прочитанную операцию положить в стек.

2. Если достигнут конец входной последовательности, вытолкнуть всё из стека в выходную последовательность и завершить работу.

 

Заметим, что порядок операндов в выходной последовательности не отличается от порядка операндов

в исходной последовательности. В выходной последовательности отсутствуют скобки.

 

Пример:

ввод:

(1 + 23 * 4)*(5 - 1)

вывод:

1 23 4 * + 5 1 - *

 

 

~stack_calc

 

Стековый калькулятор.

На входе - строка, содержащая выражение в постфиксной записи.

На выходе - строка, результат вычислений.

 

Пример:

ввод:

1 23 + 4 -

5 1 - *.

вывод:

 

Числа: целые неотрицательные.

 

Должны поддерживаться следующие двухместные

арифметические операции:

+ - * /

Каждая из них берет аргументы со стека, сначала

первый, потом - второй, выполняет над ними действие

и результат помещает на вершину стека.

 

Кроме того, должна поддерживаться операция '.'

- она берет один аргумент со стека и печатает его на вывод.

 

 

~stack_calc_module

Стековый калькулятор.
На входе - строка, содержащая выражение в постфиксной записи. На выходе - результат вычислений.

Пример: вход:
1 23 + 4 - 5 1 - *
выход: 80

Должны поддерживаться следующие двухместные арифметические операции:
+ - * /
Каждая из них берет аргументы со стека, сначала первый, потом - второй, выполняет над ними действие
и результат помещает на вершину стека.

В качестве операндов допустимы как целочисленные константы, так и имена переменных.
Имя переменной может содержать символы A-Z,a-z,0-9,_, но начинаться с цифры не может.
Решение оформить в виде отдельного.c модуля,.h файл приведен ниже.
Снабдить модульными тестами (unit-tests).

#ifndef EXEC_POSTFIX_H
#define EXEC_POSTFIX_H

/* типы лексем: константы, операции, имена переменных */
typedef enum { tt_CONST, tt_OPER, tt_ID } TokenType;

/* виды операций: сложение, вычитание, умножение, деление */
typedef enum { op_ADD, op_SUB, op_MUL, op_DIV } OperType;

/* максимальная длина имени переменной */
#define MAX_ID_LEN 40

typedef struct {
TokenType ttype;
union Value {
/* с лексемой связано одно из следующих значений */
int inum;
OperType otype;
char id[MAX_ID_LEN + 1];
} tvalue;
} Token;

typedef struct {
char id[MAX_ID_LEN + 1];
int value;
} Variable;

/* перевести текстовую строку (s) в массив лексем (*tokens).
получается массив длиной (*len).
память под выходной массив выделяется внутри функции,
а освобождается вызывающей стороной.
в случае успеха вернуть 0, иначе какой-либо код ошибки. */
int tokenize(const char *s, Token **tokens, int *len);

/* вычислить переданное постфиксное выражение (postfix, длина - len),
с использованем массива именованных переменных (vlist, длина vlen),
результат записать в *result.
в случае успеха вернуть 0, иначе какой-либо код ошибки. */
int execute_postfix(const Token *postfix, int len,
const Variable *vlist, int vlen, int *result);

#endif

 

 

~infix_to_postfix_module

Алгоритм преобразования выражения из инфиксной (привычной) записи
в постфиксную (обратную польскую).

Для перевода выражения из инфиксной формы в постфиксную с учетом приоритетов операций и скобок
существует простой алгоритм (Дейкстры). Алгоритм работает со стеком, в котором хранятся знаки операций.
Сначала стек пуст. На вход алгоритму подается последовательность лексем (числа, скобки или знаки операций),
представляющая некоторое арифметическое выражение, записанное в инфиксной форме.
Результатом работы алгоритма является эквивалентное выражение в постфиксной форме.
Вводятся приоритеты операций: открывающая скобка имеет приоритет 0, знаки '+' и '–'
— приоритет 1 и знаки '*' и '/' — приоритет 2.

1. Пока не достигнут конец входной последовательности, читать очередную лексему и выполнять с ней следующие операции:
1. если прочитан операнд (число), записать его в выходную последовательность;
2. если прочитана открывающая скобка, положить её в стек;
3. если прочитана закрывающая скобка, вытолкнуть из стека в выходную последовательность
всё до открывающей скобки, при этом сами скобки уничтожаются (удаляются из стека и в ответ не идут);
4. если прочитан знак операции, вытолкнуть из стека в выходную последовательность все операции
с большим либо равным приоритетом, а прочитанную операцию положить в стек.
2. Если достигнут конец входной последовательности, вытолкнуть всё из стека в выходную последовательность и завершить работу.

Заметим, что порядок операндов в выходной последовательности не отличается от порядка операндов
в исходной последовательности. В выходной последовательности отсутствуют скобки.

Пример: ввод:
(1 + 23 * 4)*(5 - 1)
вывод:
1 23 4 * + 5 1 - *

В качестве операндов допустимы как целочисленные константы, так и имена переменных.
Имя переменной может содержать символы A-Z,a-z,0-9,_, но начинаться с цифры не может.
Решение оформить в виде отдельного.c модуля,.h файл приведен ниже.
Снабдить модульными тестами (unit-tests).

#ifndef INFIX2POSTFIX_H
#define INFIX2POSTFIX_H

/* типы лексем: константы, операции, имена переменных */
typedef enum { tt_CONST, tt_OPER, tt_ID } TokenType;

/* виды операций: сложение, вычитание, умножение, деление,
левая и правая скобки */
typedef enum { op_ADD, op_SUB, op_MUL, op_DIV, op_LBR, op_RBR } OperType;

/* максимальная длина имени переменной */
#define MAX_ID_LEN 40

/* тип - лексема */
typedef struct {
TokenType ttype;
union Value {
/* с лексемой связано одно из следующих значений */
int inum;
OperType otype;
char id[MAX_ID_LEN + 1];
} tvalue;
} Token;

/* перевести текстовую строку (s) в массив лексем (*tokens).
получается массив длиной (*len).
память под выходной массив выделяется внутри функции,
а освобождается вызывающей стороной.
в случае успеха вернуть 0, иначе какой-либо код ошибки. */
int tokenize(const char *s, Token **tokens, int *len);

/* перевести набор лексем из инфиксного порядка в постфиксный.
память выделяется внутри функции, освобождается вызывающей стороной.
в случае успеха вернуть 0, иначе какой-либо код ошибки. */
int infix2postfix(const Token *infix, int in_len,
Token **postfix, int *out_len);

#endif

 

 

~graph_cycles

 

Определить содержит ли заданный граф циклы.

Граф - это множество вершин, и множество ребер, соединяющих их.

Граф можно задавать так:

1) Списком ребер, пример: AB, BC, AD.

2) Матрицей смежности, размера NxN, где N - количество вершин в графе.

Если на пересечении строки A и столбца B единица, то существует ребро AB.

Если ребра не имеют выделенного направления, то граф называется

неориентированным и матрица смежности будет симметрична относительно

главной диагонали.

Пример:

. | A B C D

-----------

A | 0 1 0 1

B | 1 0 1 0

C | 0 1 0 0

D | 1 0 0 0

 

Оба эти примера описывают один и тот же граф.

 

Существует простой алгоритм для определения того,

есть ли циклы в неориентированном графе:

Взять все вершины, каждая из которых связана лишь с одной другой,

вычеркнуть все соответствующие ребра и вершины. Повторять пока граф не станет

пустым или перестанет изменяться.

 

Ответить на вопрос, является ли граф циклическим.

Использовать представление графа в виде матрицы смежности.

Граф считывать со стандартного ввода:

сначала считать N - количество вершин, затем выделить массив размера NxN в куче

и заполнить его значениями 0 или 1 со стандартного ввода.

Выводить на стандартный вывод "yes" или "no".

 

 

 

 

~graph_labirynth

 

Есть лабиринт, заданный прямоугольной матрицей клеток, в которой 0 — пустая клетка, 1 — заполненная. Известны начальные координаты человечка, он может двигаться за один ход на одну клетку по вертикали или горизонтали, если новая клетка пустая. Если пустая клетка находится на краю матрицы — она выход из лабиринта. Нужно написать алгоритм достижения выхода или определения, что выхода нет.

Подсказка: использовать алгоритм поиска с откатом в глубину в графе.

Входные данные — текстовый файл с целыми числами, первые два числа — размеры матрицы, далее следует сама матрица построчно, затем — два числа — начальные координаты человечка.

Выходные данные — исходная матрица с отмеченным путем, отметить цифрой 2, или надпись «no route».

 

Пример входных данных:

5 6

0 0 1 1 1 1

1 0 0 0 0 1

1 1 1 0 1 1

1 0 0 0 0 1

0 1 1 1 1 0

4 3

Пример выходных

0 2 1 1 1 1

1 2 2 2 0 1

1 1 1 2 1 1

1 0 2 2 0 1

0 1 1 1 1 0

 

 

 

~graph_search_width

 

Поиск в ширину в графе.

Этот алгоритм позволяет найти кратчайший по количеству ребер путь между данной вершиной и всеми остальными.

Граф - это множество вершин, и множество ребер, соединяющих их.

Граф можно задавать так:

1) Списком ребер, пример: AB, BC, AD.

2) Матрицей смежности, размера NxN, где N - количество вершин в графе.

Если на пересечении строки A и столбца B единица, то существует ребро AB.

Если ребра не имеют выделенного направления, то граф называется

неориентированным и матрица смежности будет симметрична относительно

главной диагонали.

Пример:

. | A B C D

-----------

A | 0 1 0 1

B | 1 0 1 0

C | 0 1 0 0

D | 1 0 0 0

 

Оба эти примера описывают один и тот же граф.

Для поиска в ширину используются вспомогательные структуры:

1) очередь просмотра вершин.

2) массив размера N, в котором отмечаются все пройденные вершины.

3) для каждой вершины — пометка, какая вершина ей предшествует, чтобы можно было восстановить кратчайший путь — последовательность вершин.

 

Матрица, а также начальная и конечная вершины задаются пользователем.

Язык: С

 

 

 

~graph_search_depth

 

Поиск в глубину в графе или поиск с возвратами.

Этот алгоритм позволяет найти путь между данной вершиной и всеми остальными, если такой путь существует.

Граф - это множество вершин, и множество ребер, соединяющих их.

Граф можно задавать так:

1) Списком ребер, пример: AB, BC, AD.

2) Матрицей смежности, размера NxN, где N - количество вершин в графе.

Если на пересечении строки A и столбца B единица, то существует ребро AB.

Если ребра не имеют выделенного направления, то граф называется

неориентированным и матрица смежности будет симметрична относительно

главной диагонали.

Пример:

. | A B C D

-----------

A | 0 1 0 1

B | 1 0 1 0

C | 0 1 0 0

D | 1 0 0 0

 

Оба эти примера описывают один и тот же граф.

Для поиска в ширину используются вспомогательные структуры:

1) стек возвратов.

2) массив размера N, в котором отмечаются все пройденные вершины.

Матрица, а также начальная и конечная вершины задаются пользователем.

Язык: С

 

 

~bit_plane

 

Реализовать компактное хранилище для двумерного битового массива.

Каждое значение матрицы занимает в памяти один бит.

С помощью разработанной битовой матрицы реализовать рисование

линии по алгоритму Брезенхема:

http://www.codenet.ru/progr/video/alg/alg3.php

Интерфейс модуля (bitmap.h):

 

#ifndef BITMAP_H__INCLUDED

#define BITMAP_H__INCLUDED

 

typedef struct { /* допишите сами */ } BitMap;

 

/* инициализация массива нужной размерности,

возврат 1 - все хорошо, 0 - не хватило памяти */

int bmp_new(BitMap *bmp, int width, int height);

 

/* освободить память, занимаемую массивом */

void bmp_free(BitMap *bmp);

 

/* извлечь значение из строки y, столбца x,

если координаты выходят за пределы - всегда возвращать 0 */

int bmp_get(const BitMap *bmp, int x, int y);

 

/* установить значение бита = value в матрице, в строке y, столбце x.

предыдущее значение вернуть в качестве результата функции,

если координаты выходят за пределы - всегда возвращать 0 */

int bmp_set(BitMap *bmp, int x, int y, int value);

 

/* нарисовать линию по алгоритму Брезенхема,

точки рисовать значением value */

void bmp_line(BitMap *bmp, int x1, int y1, int x2, int y2, int value);

 

#endif

 

Для отладки нужно матрицу выводить на стандартный вывод.

 

 

 

 

~pas_filter_comments

 

Задание:

Программа - текстовый фильтр, отбрасывающий комментарии в стиле языка Object Pascal,

но сохраняющая все остальное без изменений.

В Object Pascal предусмотрено 3 типа комментариев: скобочные { }, (* *)

и строчный //, который комментирует текст до конца строки.

Скобочные комментарии одного типа не могут быть вложенными, например нельзя так:

{ { } }, разных типов — могут быть вложенными, например: (* { } *).

Программа считывает символы со стандартного ввода, выводит на стандартный вывод.

Внутри нее нужно устроить конечный автомат, устройство которого - состояния и переходы

между ними - отразить в пояснительной записке.

Язык программирования: ANSI C

~int_stack_module

 

 


Дата добавления: 2015-11-04; просмотров: 35 | Нарушение авторских прав




<== предыдущая лекция | следующая лекция ==>
 | Мiнiстерство освіти і науки України

mybiblioteka.su - 2015-2024 год. (0.072 сек.)