Как прочитать матрицу из файла c
Обновлено: 21.11.2024
Я пытаюсь познакомиться с C++ 11/14, поэтому, пожалуйста, скажите мне, можно ли код ниже написать более "современно". Или, конечно, если бы его можно было как-то улучшить.
Функция buildInput считывает содержимое файла и строит на его основе матрицу.
Эта функция строит входные данные для игры Sokoban из файла. По сути, он строит «карту» (матрицу) с несколькими типами объектов, размещенных на ней.
Файл имеет следующий формат:
Например, для следующего содержимого файла:
код построит матрицу
\$\begingroup\$ Пожалуйста, добавьте объяснение, показывающее образец ввода. На данный момент не очень понятно, чего вы (и код) ожидаете. \$\конечная группа\$
\$\begingroup\$ Я откатил последнее редактирование. Посмотрите, что вы можете и чего не можете делать после получения ответов. \$\конечная группа\$
2 ответа 2
Я вижу некоторые вещи, которые могут помочь вам улучшить код.
Подумайте о пользователе
Предоставленный пример ввода требует 21 числа, чтобы компьютер мог создать матрицу, содержащую только 16. Здесь много избыточности! Мне кажется, что простое использование вашего примера вывода в качестве входного формата имело бы гораздо больше смысла и требовало бы меньше места, меньше ввода и меньше интерпретаций.
Лучше очищайте пользовательский ввод
Если я изменю последнюю строку примера ввода на 1 9 9, он попросит код инициализировать местоположение, находящееся за пределами вектора, и на моей машине компьютер выйдет из строя, и программа умрет. Было бы разумно проверить некоторые границы.
Передавать поток, а не имя файла
Текущий дизайн довольно негибкий, поскольку в качестве входных данных может использоваться только реальный файл. Я бы рекомендовал сделать его более общим и принимать std::istream & в качестве параметра, а не имя файла.
Используйте лучшую структуру данных
Выбор вектора векторов для матрицы не очень удачен, потому что, в отличие от матрицы, ничто не гарантирует, что все векторы имеют одинаковый размер. Я бы рекомендовал создать собственный пользовательский объект, который скрывает запутанные детали фактического хранилища (это может быть std::array или один std::vector ), но может выполнять проверку и извлечение границ, используя ту же систему координат. Пример показан ниже.
Используйте экстрактор друзей вместо отдельной функции
Вместо того, чтобы иметь отдельную функцию, было бы лучше иметь возможность написать примерно такой код:
Для этого мы могли бы написать экстрактор. Вот набросок примера:
Несколько слов об адресации отдельных квадратов
В комментариях был задан вопрос, может ли выполнение математических операций (умножения) занять больше времени, чем адресация вектора векторов. На моей 64-битной машине с Linux, использующей gcc 6.2.1 с оптимизацией -O3, я закодировал две разные версии.
Во-первых, вот исходный код теста:
Обратите внимание, что это плохая программа, в которой отсутствует всякая проверка ошибок, но цель состояла только в том, чтобы извлечь язык ассемблера для двух версий fetch . Во-первых, эта версия
создал этот ассемблерный код
создал этот ассемблерный код
Мне не удалось обнаружить каких-либо различий во времени при тестировании, которое я провел, но мы видим, что разница заключается в том, что для версии с вектором векторов выполняется 5 выборок памяти по сравнению с тремя для версии с умножением. Если структура оказывается в кеше (вероятно, так было в моем тестировании, когда я использовал небольшие размеры), они обе имеют примерно одинаковую продолжительность. В случае промаха кеша версия с умножением, скорее всего, будет быстрее.
Я всегда рекомендую вам измерять его на своем собственном компьютере с вашими собственными данными, чтобы определить, что лучше для ваших целей.
Как выполнить умножение матриц на языке программирования C с помощью текстового файла? Если это вопрос, который привел вас на этот сайт, то вы находитесь в правильном месте. В этой статье вы узнаете, как выполнять умножение матриц, читая две матрицы из двух текстовых файлов и сохраняя результат в текстовом файле.
Умножение матриц с использованием программирования C
Прежде чем перейти непосредственно к исходному коду, давайте четко разберемся в проблеме. Во-первых, мы сгенерируем две матрицы в два разных текстовых файла. Во-вторых, мы прочитаем две матрицы из двух разных текстовых файлов и сохраним их в массиве для выполнения матричного умножения. Затем, наконец, мы выполняем умножение матриц и записываем результат в текстовый файл.
Создание двух матриц
Мы будем использовать функцию «rand» для генерации элемента матрицы. Вы также можете создать матрицу вручную. Затем мы сохраним или запишем данные в файлы matrixA.txt и matrixB.txt.
rand(): генерирует случайное число в диапазоне от 0 до RAND_MAX. Вы можете иметь свой собственный диапазон случайных чисел с помощью некоторых трюков с функцией rand.Например, если вы хотите, чтобы ваше случайное число находилось в диапазоне от 0 до 9, используйте функцию модуля вместе с rand(т.е. rand()%10).
Запись и чтение элемента матрицы
Чтобы записать элемент матрицы в текстовый файл, мы будем использовать функцию «fprintf». Для чтения матричного элемента из текстового файла воспользуемся функцией «fscanf».
fprintf(): записывает отформатированные данные в файл. Синтаксис: fprintf(FILE *ptr, const char *format, …).
fscanf(): считывает данные из файла, на который указывает указатель файла. Синтаксис: fscanf(FILE *ptr, const char *format, …).
Некоторые другие функции в c, которые можно использовать для чтения и записи данных в файлы, следующие:
- getc() и putc() — чтение и запись в файл одного символа.
- getw() и putw() — чтение и запись целого числа в файл.
Псевдокод для умножения матриц
Входные данные: Входными данными для программы являются матрица A и матрица B разных размеров.
Вывод: Произведение матрицы A и матрицы B в матрицу C.
Этот псевдокод содержит только алгоритм умножения матриц. Как читать и записывать данные, можно найти в исходном коде ниже.
Исходный код для умножения матриц с использованием текстового файла.
Ввод: Мы сгенерируем матрицу A и матрицу B и запишем их в текстовые файлы matrixA.txt и matrixB.txt соответственно. Эти два текстовых файла матриц будут входными данными для умножения основной матрицы.
Вывод: Вычислите произведение матрицы A и матрицы B, затем запишите результат в файл matrixC.txt.
Этот исходный код работает, только если вы создаете текстовый файл матрицы автоматически, как я сделал выше. Если вы хотите использовать тот же исходный код с созданным вручную текстовым файлом матрицы, вам следует иметь представление о размерности матриц и инициализировать глобальные переменные arow, acol, brow и bcol в файле приведенный выше код, и вы можете удалить функцию generateMatrix().
Кроме того, вы можете использовать приведенный ниже код для выполнения умножения матриц на созданную вручную матрицу. Вам не нужно указывать размер матрицы, код проверит размер и увидит, можно ли перемножить две матрицы, и выполнит задачу.
Ограничение приведенного выше кода заключается в том, что вы можете прочитать матричный элемент с размерами не более 1000 на 1000. Если вы превысите указанный выше размер (1001 * 1001), вы получите ошибку сегментации (дамп ядра).
Сложность матричного умножения во время выполнения
Глядя на приведенный выше код, может быть ясно, что время выполнения вышеуказанного алгоритма составляет O(n^3). Поскольку есть три цикла for, перебирающих матрицу для выполнения матричного умножения.
Поэтому время выполнения матричного умножения равно O(n^3).
Заключение
Из этой статьи вы узнали, как выполнять умножение матриц. Особенно на языке программирования C с текстовым файлом в качестве входной матрицы для программы. Тот же алгоритм можно реализовать на любом другом языке программирования. Просто имена некоторых функций и синтаксис будут другими. Кроме того, вы научились читать и писать файл в программировании на C. Если эта статья была вам полезна, подпишитесь на наш веб-сайт, чтобы получать последние обновления сообщений в блоге.
Я новичок в технологиях. Изучать и узнавать что-то новое — это то, чем я занимаюсь. Я делюсь тем, что знаю, в своем блоге.
Библиотека ANSI C для ввода-вывода Matrix Market
Числовые данные в форматах файлов Matrix Market можно легко обрабатывать с помощью вариантов функций fscanf() и fprintf(). Единственная нетривиальная проблема состоит в том, чтобы выяснить, какая матрица представлена в файле Matrix Market. Из-за широкого спектра возможностей нецелесообразно иметь одну функцию для обработки каждого случая (более того, большинство приложений будут поддерживать только подмножество этих типов матриц). Вместо этого мы предоставляем утилиты, которые идентифицируют и управляют только информацией о типе и размере в файлах MM, оставляя фактические механизмы чтения и записи управляющему приложению или процедурам ввода-вывода более высокого уровня.
<ПР>Исходный код
Документация
<УЛ>mm_read_banner()
mm_read_banner — определяет тип матрицы, представленной в файле Matrix Market
ОБЗОР
ОПИСАНИЕ
Координата матрицы %%MatrixMarket действительно общая
и возвращает характеристики матрицы. Дескриптор файла f определен в "stdio.h" и предполагается, что он открыт для чтения. Предопределенный дескриптор stdin можно использовать для чтения из стандартного ввода. t указывает на внутреннюю структуру, описывающую характеристики матрицы. Этот MM_typecode более эффективен и удобен, чем сохранение явного баннера. функции запроса, такие как mm_is_complex(t), доступны для извлечения этой информации.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ОШИБКИ
- MM_PREMATURE_EOF, если в первой строке файла присутствуют не все элементы.
- MM_NO_HEADER, если файл не начинается с "%%MatrixMarket".
- MM_UNSUPPORTED_TYPE, если описание непонятно.
ПРИМЕРЫ
СМОТРИТЕ ТАКЖЕ
mm_read_mtx_crd_size()
mm_read_mtx_crd_size — чтение информации о размере разреженной матрицы (формат координат) в файле Matrix Market
ОБЗОР
ОПИСАНИЕ
После обработки баннера Matrix Market функция mm_read_mtx_crd_size() считывает необязательные комментарии и инициализирует переменные размера M (количество строк), N (количество столбцов) и nz (количество ненулевых значений). Предполагается, что считываемая матрица имеет формат координат.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ОШИБКИ
- MM_PREMATURE_EOF, если перед обработкой этих трех значений обнаруживается конец файла.
СМОТРИТЕ ТАКЖЕ
mm_read_mtx_array_size()
mm_read_mtx_array_size — чтение информации о размере плотной матрицы (формат массива) в файле Matrix Market
ОБЗОР
ОПИСАНИЕ
После обработки баннера Matrix Market функция mm_read_mtx_crd_size() считывает необязательные комментарии и инициализирует переменные размера матрицы M (количество строк), N em> (количество столбцов). Предполагается, что считываемая матрица имеет формат массива.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ОШИБКИ
- MM_PREMATURE_EOF, если конец файла встречается до чтения M и N.
СМОТРИТЕ ТАКЖЕ
mm_write_banner()
mm_write_banner - записывать информацию о типе матрицы в файл Matrix Market
ОБЗОР
ОПИСАНИЕ
mm_write_banner() выводит первую строку файла Matrix Market, которая состоит из токена "%%MatrixMarket", за которым следует список атрибутов, например.
Матричная координата %%MatrixMarket реальная общая
Описатель файла f определен в "stdio.h" и предполагается, что он открыт для записи. Предопределенный дескриптор stdout можно использовать для чтения из стандартного вывода. t указывает на внутреннюю структуру, описывающую характеристики матрицы. Этот MM_typecode более эффективен и удобен, чем сохранение явного баннера. Для установки этих характеристик можно использовать различные функции назначения, такие как mm_set_complex(&t).
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ПРИМЕРЫ
СМОТРИТЕ ТАКЖЕ
mm_write_mtx_crd_size()
mm_write_mtx_crd_size — запись информации о размере плотной матрицы (формат массива) в файл Matrix Market
ОБЗОР
ОПИСАНИЕ
Запишите размеры матрицы M x N и общее количество ненулевых элементов nz в файл Matrix Market. Обычно вызывается после mm_write_banner().
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ДИАГНОСТИКА
Это простая функция для записи трех целых чисел в f с помощью fprintf(). Он включен в библиотеку только для полноты, как аналог mm_read_mtx_crd_size().
СМОТРИТЕ ТАКЖЕ
mm_write_mtx_array_size()
mm_write_mtx_array_size — запись информации о размере плотной матрицы (формат массива) в файл Matrix Market
ОБЗОР
ОПИСАНИЕ
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ДИАГНОСТИКА
Это простая функция для записи двух целых чисел в f с помощью fprintf(). Он включен в библиотеку только как аналог mm_read_mtx_array_size().
СМОТРИТЕ ТАКЖЕ
ММ_ИС
mm_is_matrix, mm_is_sparse, mm_is_coordinate, mm_is_dense, mm_is_array, mm_is_complex, mm_is_real , mm_is_pattern, mm_is_integer, mm_is_symmetric, mm_is_general, mm_is_skew, mm_is_hermitian -функции запроса матричного типа
ОБЗОР
ОПИСАНИЕ
Функции MM_QUERY обеспечивают логическую проверку переменных кодов типов матриц (MM_typecode) для заданного свойства хранилища. Функции возвращают 0, если false, иначе 1. Обратите внимание, что эти свойства относятся только к схеме хранения, а не к математическим свойствам. Например, математически симметричная матрица, хранящаяся как с верхней, так и с нижней треугольными половинками, будет оцениваться как mm_is_symmetric() false.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ДИАГНОСТИКА
СМОТРИТЕ ТАКЖЕ
MM_SET
mm_set_matrix, mm_set_sparse, mm_set_coordinate, mm_set_dense, mm_set_array, mm_set_complex, mm_set_real , mm_set_pattern, mm_set_integer, mm_set_symmetric, mm_set_general, mm_set_skew, mm_set_hermitian, mm_clear_typecode, mm_initialize_typecode --функции запроса матричного типа
ОБЗОР
ОПИСАНИЕ
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ДИАГНОСТИКА
СМОТРИТЕ ТАКЖЕ
mm_typecode_to_str()
ОБЗОР
ОПИСАНИЕ
mm_typecode_to_str преобразует MM_typecode в мнемоническую строку. Это можно использовать как часть диагностики и отчетов об ошибках. (См. "example_read.c" для возможного использования.)
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ДИАГНОСТИКА
mm_typecode_to_str внутренне использует strdup(), поэтому возвращаемая строка должна быть освобождена, чтобы избежать утечек памяти.
Чтение матриц из файлов может занять много времени в зависимости от размера матрицы. read.matrix реализует довольно эффективную процедуру для чтения разреженных матриц и возврата плотных матричных аналогов.
Использование
Аргументы
Файл или подключение для чтения
Существуют ли строки заголовков, определяющие все возможные строки и столбцы. Если это неверно, то определенные элементы триплета будут создавать полный набор строк и столбцов.
Количество пропущенных строк. Это предполагает наличие одной строки заголовка, которая пропускается.
Если заголовок равен TRUE, номер строки, которая определяет row.ids. Если header == FALSE, row.ids для использования в матрице
Если заголовок равен TRUE, номер столбца, определяющий идентификаторы столбцов. Если заголовок == FALSE, идентификаторы столбцов, используемые для матрицы
Классы, используемые для столбцов в файле триплета
Функция, используемая для создания разреженного представления, которое затем преобразуется в плотную матрицу
Дополнительная функция, используемая для фильтрации/очистки входных данных и/или идентификаторов строк/столбцов. Подпись filter.fn должна содержать аргументы для data, row.id и col.id
Дополнительные аргументы для передачи в конструкторскую часть реализации
Подробнее
Матрицы размером порядка тысячи могут медленно загружаться в R. 'read.matrix' обеспечивает эффективную реализацию для чтения разреженных матриц в форме триплетов из файла или другого соединения. В этой версии удалены зависимости от других пакетов и показано улучшение скорости по сравнению с этими методами.
Основное преимущество этой функции заключается в том, что по сравнению с пакетом slam можно использовать именованные строки и столбцы, а не целочисленные индексы. Другая основная причина заключается в том, что при наличии памяти вычисления с плотной матрицей могут выполняться быстрее, чем их разреженные аналоги, не говоря уже о наличии более широкого набора доступных операторов.
Если заголовок == TRUE, имена строк и/или столбцов считываются из файла. Предполагается, что имена должны быть разделены запятыми в одной строке.
Можно использовать различные методы для построения представления разреженной матрицы, которое используется в качестве основы для построения плотной матрицы. В настоящее время доступна только функция assign_matrix_dense, которая хорошо работает с матрицами в форме триплетов.
Читайте также: