Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - STL

Ответить
Настройки темы
C/C++ - STL

Новый участник


Сообщения: 21
Благодарности: 1

Профиль | Отправить PM | Цитировать


Изменения
Автор: .::.DIMA.::.
Дата: 16-03-2013
Решено

Отправлено: 16:43, 22-04-2009

 

Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


.::.DIMA.::., дабы многократно не перечитывать файл, его содержимое можно загрузить в память и работать с ней.
В примере про функцию fread() по ссылке в теме Бинарные файлы как раз так и поступили.

Отправлено: 19:37, 22-04-2009 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить 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

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить 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



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - STL

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
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




 
Переход