Лекция 8 задач

реклама
1
Лекция 8. Вопросы к экзамену и примеры экзаменационных
задач
В билете 2 задачи, время – 2,5 часа. Сдаётся и
проверяется письменная работа, а не файл. Пользоваться
можно
компьютером
и
своими
лекциями
(задачами).
Интернет на экзамене отключен. В случае спорной оценки
может быть устная беседа по темам задач билета.
Тема задачи 1 – работа со строками, указателями или
динамическими массивами.
Тема задачи 2 – работа с текстовыми или бинарными
файлами.
Основные алгоритмические приемы для решения задач из
билетов:
 Типовые алгоритмы (сумма, среднее, произведение,
количество, максимум, минимум, обработка всех
элементов вектора и матрицы);
 Динамическое
выделение
памяти
под
вектор
и
матрицу, работа с динамическими данными;
 Сравнение элементов вектора или последовательности
«каждый с каждым» в двойном цикле (сортировка,
перестановка);
 Стандартные функции работы со строками, заданными
указателями или строками класса string;
 Посимвольная обработка строк с помощью указателей:
 Посимвольное, форматное, построчное чтение данных
из текстовых файлов. Запись данных в файлы;
 Чтение и запись бинарных данных.
Если размеры строки или файла не указаны в условии,
они предполагаются произвольными, иначе соблюдать
размеры
и
ограничения
из
условия.
Программа
обязательно тестируется, для теста достаточно заданных
в коде примеров, ввод с консоли необязателен. Проверка
корректности данных нужна, если ограничения на их
значения указаны в условии. Разбиение кода на функции
обязательно только если явно указано в условии, иначе
– на усмотрение студента.
2
Пример 1. Текстовый файл содержит произвольные слова
на английском языке, по 1 слову в строке, не более 40
слов в файле, длина слова ограничена 80 символами.
Переписать слова в другой файл, отсортировав их в
алфавитном порядке.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char s[40][80];
char *p[40], *temp;
FILE *fp;
int i, j, n = 0;
fp = fopen("var01.txt", "rt");
if (fp == NULL) {
printf("\nCan't open file to read!");
exit(1);
}
while (1) {
fscanf(fp, "%s", &s[n][0]);
p[n++] = &s[n][0];
if (feof(fp)) break;
}
for (i = 0; i<n - 1; i++)
for (j = i + 1; j<n; j++) {
if (strcmp(p[i], p[j])>0) {
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
fclose(fp);
fp = fopen("res01.txt", "wt");
if (fp == NULL) {
printf("\nCan't open file to write!");
exit(1);
}
for (i = 0; i<n; i++) fprintf(fp, "%s\n", p[i]);
fclose(fp);
fflush(stdin); getchar(); return 0;
}
3
Пример 2. Подсчитать количество строк и символов в
произвольном
файле,
а
также
процент
символов,
являющихся пробельными (пробел, табуляция, возврат
каретки и перевод строки). Строка завершается парой
символов «возврат каретки и перевод строки». При
подсчете количества символов пара символов «возврат
каретки и перевод строки» не интерпретируется как один
символ.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *fp;
char c;
long count = 0, lines = 0, divs = 0;
float percent;
fp = fopen("var01.txt", "rb");
if (fp == NULL) {
printf("\nCan't open file");
exit(1);
}
while (1) {
fread(&c, 1, 1, fp);
if (feof(fp)) break;
count++;
if (c == '\r') {
fread(&c, 1, 1, fp);
if (feof(fp)) break;
count++;
if (c == '\n') lines++;
}
if (strchr(" \t\r\n", c)) divs++;
}
percent = divs * 100 / count;
printf("\n Count=%ld", count);
printf("\n Lines=%ld", lines + 1);
printf("\n Divs =%4.2f%", percent);
fclose(fp);
fflush(stdin); getchar(); return 0;
}
4
Пример 3. Задана строка s произвольного размера.
Реализовать подпрограмму удаления символов из строки,
начиная с символа номер n, n≥0 до символа номер k
включительно, k≥n. Подпрограмма возвращает указатель
на
полученную
строку
или
NULL,
если
удаление
невозможно.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
char *str2(char *s, int n, int k) {
char *p = s;
int i, len, l;
len = strlen(s);
if (n<0 || n>len - 1 || k<0 || k>len - 1 || n>k) return NULL;
s += n;
l = k - n + 1;
for (i = n; i<len; i++, s++) *s = *(s + l);
*s = '\0';
return p;
}
int main() {
char *s = new char[20];
//не char *s="Hello, world!";
strcpy(s, "Hello, world!"); //- нельзя будет менять строку!
char *p = str2(s, 3, 6);
if (p == NULL) printf("\n Impossible!");
else printf("\n Result is \"%s\"", p);
fflush(stdin); getchar(); return 0;
}
Пример
4.
Прочитать
из
бинарного
файла
данных
динамический
массив,
состоящий
из
целых
чисел.
Определить, сколько раз в нём встречается максимальное
значение
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
char name[80];
printf("\nFile name? ");
scanf("%s", name);
//fgets добавит \n в конце строки, надо удалять
FILE *f = fopen(name, "r+b");
5
if (f == NULL) { printf("\nCan't open file"); return 1; }
fseek(f, 0, SEEK_END);
long size = ftell(f);
//fgetpos под Windows может создать проблемы
int n = (int)size / sizeof(int);
fseek(f, 0, SEEK_SET);
int *a = new int [n];
if (a == NULL) { printf("\nNo memory"); return 2; }
fread(a, sizeof(int), n, f);
int max = a[0], kol = 0;
for (int i = 0; i<n; i++) {
printf("%d ", a[i]);
if (a[i]>max) { max = a[i]; kol = 1; }
else if (a[i] == max) kol++;
}
printf("\nMax=%d,kol=%d", max, kol);
fflush(stdin); getchar(); getchar(); return 0;
}
Исходя из того, что каждое число в бинарном файле
займёт sizeof(int)=4 байта (в 32-разрядной системе),
файл теста сделаем, например, таким:
0033100000331000
Видно, что здесь всего 4 числа и каждое число
повторяется дважды.
Скачать