Проект Эйлера (22 задача) решается легко и быстро (5 – 10 миллисекунд) при применении алгоритма сортировки массива слиянием.
Узнать больше в телеграм-канале: ProjectEuler++
Используйте names.txt (щелкнуть правой кнопкой мыши и выбрать ‘Save Link/Target As…’), текстовый файл размером 46 КБ, содержащий более пяти тысяч имен. Начните с сортировки в алфавитном порядке. Затем подсчитайте алфавитные значения каждого имени и умножьте это значение на порядковый номер имени в отсортированном списке для получения количества очков имени.
Например, если список отсортирован по алфавиту, имя COLIN (алфавитное значение которого 3 + 15 + 12 + 9 + 14 = 53) является 938-м в списке. Поэтому, имя COLIN получает 938 × 53 = 49714 очков.
Какова сумма очков имен в файле?
Измеряем время работы программы
Используемые при расчете функции
Описание применяемых функций будет ниже, здесь лишь опишем общий алгоритм:
Для хранения содержимого файла создадим массив text_arr[] длиной 50000, потому что в условии заранее сказано о весе файла в 46 кБ. Однако, если в итоге понадобится ее изменить, то это будет легко сделать, изменив значение в:
При помощи функции open_file() открываем файл “euler22text.txt” и копируем его в созданный ранее массив. При этом он будет содержать не только имена, но и все символы, содержащиеся в файле:
Потому и, чтобы легче было сортировать список, создадим еще один массив (смотрите выше):
В нем будем хранить полученные с помощью функции parser_names() индексы первых букв имен в массиве text_arr[]. Т.е. если первая буква слова “MARY” расположена в:
… а “PATRICIA”
… то массив name_arr[] в итоге будет заполнен примерно так:
Далее, с помощью функции merge_sort() имена сортируются. Однако при этом в массиве text_arr[], где имена фактически сохранены, ничего не трогается. Перемещаются лишь их индексы в массиве name_arr[]:
Изменение порядка индексов, в итоге означает изменение порядка слов:
В итоге после сортировки остается лишь посчитать с помощью функции get_name_score() искомую сумму очков имен.
Для измерения времени работы программы подключаем библиотеку time.h:
С помощью функции clock() измеряем время начала (begin) и окончания (end) работы программы. В итоге время работы будем находить как разность между ними.
(double) приводит число (в данном случае – результат вычислений end – begin) к вещественному типу данных double (числа с точкой)
CLOCKS_PER_SEC – это константа, сохраненная в библиотеке и зависящая от типа устройства, на котором запускается программа. В данном случае – это просто 1000
Используем здесь стандартные функции языка Си:
Также функция выводит сообщение об ошибке, если невозможно прочитать файл (например, неправильно написан путь к нему). Кроме того, выводится сообщение о количестве скопированной информации. Это также полезно знать, потому что иначе, при недостаточной длине массива будет скопирован не весь файл.
Подключив <ctype.h> мы получаем возможность использовать стандартный набор функций для анализа символов. Однако понадобится нам лишь одна:
Работа parser_name() реализована при помощи данной функции и флага start_name (первоначально false):
Проверка выхода за пределы массивов text_arr[] и name_arr[] реализована с помощью отдельной функции – input_more_limit().
Данная проверка вынесена отдельной функцией, потому что иначе пришлось бы многократно писать одно и тоже в каждой функции. Она выводит предупреждение, в котором пишет название функции в которой она сработала, название и значение проверяемой переменной и параметры, которые она превысила. Также она вернет true, в случае превышения, что позволит в прервать функцию, в которой она используется через return. Или, если выход параметра за пределы в итоге не критичен, как-либо иначе это использовать.
Функция использует вышеупомянутую функцию isalpha(). Она проходит по двум именам и сравнивает буквы между собой:
В итоге функция возвращает true – нет необходимости менять слова местами, false – если необходимо.
Данная функция служит, чтобы скопировать в один массив (receive_arr[]) часть другого (sourse_arr[]). Поскольку копируется лишь часть массива (lenght элементов начиная индекса start_indx), потому контролируется невыход за пределы только второго массива. Количество в итоге скопированных в массив элементов возвращается функцией.
По традиции хотелось бы выразить глубочайшую признательность Сергею Балакиреву за его титанический труд по созданию бесплатных курсов и в частности, за “Язык программирования C/C++ для начинающих“.
© 2023-2024 | eulerproject.ru