2D итератор для цикла - PullRequest
       8

2D итератор для цикла

0 голосов
/ 21 ноября 2018

У меня проблемы с реализацией класса итератора в отношении .end ().Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь использовать цикл for с моим классом итератора;в настоящее время он останавливается непосредственно перед последним элементом в 2D-векторе.Однако я хочу, чтобы он прошел один элемент за последним элементом, не вызывая ошибки компилятора, и включил последний символ в оператор печати. ​​

main.cpp

// file contents            
// aaa                          
// bbb                          
// cce 

// factory method (adds file contents to 2D <char> vector)
Base *a = Base::create("file");       
cout << *a; // overloaded '<<'

Prints

a a a b b b c c e

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

for(auto it = a->begin(); it != a->end(); it++) 
    cout << *it << ' ';

Печатает

a a a b b b c c

.end печатает следующее

Base::iterator it = aa->end();
cout << *it << '\n';
// prints e

Когда я пытаюсь выполнить цикл while, он включает последний символ.

// Note: my iterator class is a nested class inside Base class.

const Base::iterator et = a->begin(); 
int i = 0;
while(i < 13) {
    cout << *et << ' ';
    et++;
}

Печатает

a a a b b b c c e e e e e

Я понимаю, что-> end () должен указывать сразу за последним символом, но я не понимаю, как это реализовать.Когда я увеличиваю последнее значение в моем операторе ++ (int), оно отображает ошибку сегментации.В настоящее время мой перегруженный метод увеличения останавливается на последнем символе и не проходит мимо него.С учетом вышесказанного, как мне реализовать метод ++ (int) для включения последнего элемента при печати из цикла for?Я должен добавить нулевой элемент к вектору или что-то в этом роде?

Внутри Base.cpp

// This function is whats causing the issue. I know it looks ugly.
Base::iterator Base::iterator::operator++(int) {

    // base is a Base *, x and y are coordinates for 2D vector
    Base::iterator temp(base, x, y); // save value 

    // if iterator has not reached end
    if( !((x == base->vec.size()-1) && (y == base->vec[0].size()-1)) )
    {
      // if y < row size
      if(y < base->vec[0].size()-1)
          y++;

      // if y has reached end of row, increment x and start y on a new row
      else if(x < base->vec.size() && y == base->vec[0].size()-1) {
          y=0;
          x++;
      }
    }
    return temp;
}

Base::iterator Base::begin() {
    return Base::iterator(this, 0, 0);
}

Base::iterator Base::end() {
    return Base::iterator(this, vec.size()-1, vec[0].size()-1);
}

Остальная часть Base.cpp

#include "Base.h"

using namespace std;

// Factory method (instantiates 2D vector with file contents)
Base *Base::create(string filename) {/*removed irrelevant code */}

Base::~Base(){}

// prints 2D vector
ostream &operator<<(ostream &os, const Base &val){/*removed irrelevant code*/}

Base::iterator::iterator(Base *b, int m, int n): base(b), x(m), y(n) {}
Base::iterator::~iterator(){}

// returns a character inside 2D vector
char &Base::iterator::operator*() const {
    return base->vec[x][y];
}  

bool Base::iterator::operator==(const Base::iterator& rhs) const {
    return base->vec[x][y] == *rhs;
}

bool Base::iterator::operator!=(const Base::iterator& rhs) const {
    return base->vec[x][y] != *rhs;
}

// Bunch of other functions

Любойбыла бы признательна за помощь.

1 Ответ

0 голосов
/ 21 ноября 2018

Base::iterator(this, vec.size()-1, vec[0].size()-1); это вернет действительный последний элемент.Поэтому вам нужно изменить его на Base::iterator(this, vec.size(), 0);, а также обновить условия, чтобы переключиться на новую строку в цикле.

Что-то вроде:

// if iterator has not reached end
if(x < base->vec.size())
{
  ++y;

  // if y has reached end of row, increment x and start y on a new row
  if(y >= base->vec[0].size() {
      y=0;
      ++x;
  }
}

Также итераторы ошибочны:

bool Base::iterator::operator==(const Base::iterator& rhs) const {
    return base == rhs.base && x == rhs.x && y == ris.y;
}

bool Base::iterator::operator!=(const Base::iterator& rhs) const {
    return !(base == rhs.base && x == rhs.x && y == ris.y);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...