C/C++ - STL
|
Новый участник Сообщения: 21 |
Профиль | Отправить PM | Цитировать
Решено
|
|
Отправлено: 16:43, 22-04-2009 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать .::.DIMA.::., дабы многократно не перечитывать файл, его содержимое можно загрузить в память и работать с ней.
В примере про функцию fread() по ссылке в теме Бинарные файлы как раз так и поступили. |
Отправлено: 19:37, 22-04-2009 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать В зависимости от идеи можно поступить по-разному.
Допустим матрица хранится в виде упорядоченного списка ненулевых элементов: {row, col, value} тогда наша задача пробежать 2 файла и записать 3-й файл с ненулевым результатом в таком же упорядоченном виде. Используем алгоритм merge struct cell_t { unsigned row; unsigned col; double value; // для сортировки friend bool operator<(const cell_t& a, const cell_t& b) { return a.row<b.row || (a.row==b.row && a.col<b.col); // для удобства потом friend bool operator==(const cell_t& a, const cell_t& b) { return a.row==b.row && a.col==b.col; // ввод-вывод friend ostream& operator<<(ostream& os, const cell_t& a) { return os << a.row << " " << a.col << " " << a.value; } friend istream& oeprator>>(istream& is, cell_t& a) { return is >> a.row >> a.col >> a.value; } }; struct mixer { cell_t prev; ostream_iterator<cell_t,char> output_iter; mixer() : prev(), output_iter(cout, "\n") { } // строим хитрый итератор mixer& operator*() {return *this;} // так чтобы *iter=a давало нужный эфект void operator=(const cell_t& a) { if (prev==a) prev.value += a.value; else { if (prev.value) *output_iter = prev; prev = a; } } void main() { ifstream matrix1("matrix1.txt"); ifstream matrix2("matrix2.txt"); mixer mixer1; // экономим копирования (передаём в шаблон ссылку, а не объект) *merge( istream_iterator<cell_t>(matrix1), istream_iterator<cell_t>(), istream_iterator<cell_t>(matrix2), istream_iterator<cell_t>(), static_cast<mixer&>(mixer1)) = cell_t(); // необходимо чтобы выгрузить последний накопленный результат } |
Отправлено: 22:18, 22-04-2009 | #3 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Итератор - это заменитель указателя в с++. Он даёт универсальное представление указателя на элемент контейнера для шаблонов перебора в с++. Пример шаблона копирования:
template<typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) { for(; first!=last; ++first, ++result) *result = *first; return result; } OutputIterator - предназначен для вывода в поток, во всех алгоритмах используются только конструции *iterator=..., и ++iterator или iterator++; (кстати, если компилятор будет ругаться при сборке на operator++() или operator++(int), надо его добавить, пустой) InputIterator - для ввода с потока ...=*iterator и ++iterator или iterator++. При этом понимается, что значение надо брать и присваивать один раз. для OutputIterator и InputIterator как правило явный конструктор без параметра строит итератор конца потока. ForwardIterator - позволяет чтение, запись, оператор ++ (например для стека) BidirectionalIterator - позволяет чтение, запись, операторы ++,-- (например для списка) RandomAccessIterator - позволяет всё, что можно делать с указателем Попробуем раскрыть шаблон copy с классом merge&: // merge merge1 // copy(istream_iterator<cell_t>(cin), istream_iterator<cell_t>(), static_cast<merge&>(merge1)) merge& copy(istream_iterator<cell_t,char> first, istream_iterator<cell_t,char> last, merge& result) { // *first прочитает оператором >> и вернёт значение cell_t из потока // *result вернёт result // result =... вызовет merge::operator=(const cell_t&), который запишет в поток вывода результат // merge::operator++() лучше оставить пустым {} тогда ++result просто пропустится for(; first!=last; ++first, ++result) *result = *first; // если идти дальше, у istream_iterator пустой operator++, а operator==(const istream_iterator& iter2) // возвращает что-то вроде _stream.good()==iter2._stream.good(); // помним, что last._stream.good() даёт false // получили примерно следующее: for(; first._stream.good()!=last._stream.good(); ) result.merge::operator=((first._stream>>first._value ? first._value : cell_t())); return result; } |
Отправлено: 08:07, 23-04-2009 | #4 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
C/C++ - STL Stack | delight | Программирование и базы данных | 1 | 10-12-2009 07:37 | |
C/C++ - STL работа со стеком | alextrs | Программирование и базы данных | 2 | 28-04-2008 18:41 | |
heap @ c++ stl | pva | Программирование и базы данных | 10 | 12-04-2005 15:58 | |
STL и multimap | Crew | Программирование и базы данных | 5 | 28-11-2004 18:23 | |
C++Builder4 & C++stl | pva | Программирование и базы данных | 2 | 12-10-2004 07:32 |
|