两个带有 STL 迭代器的循环

Two loops with STL iterators

如何使用 STL 迭代器重写这个?

for (int i = 0; i < board.size(); i++) {
      for (int j = 0; j < board[i].size(); j++) {
        if (board[i][j] == '*') {
          if (board[i][j + 1] == '*') {
            j++;
            sum += a;
          } else {
            sum += b;
          }
        }
      }
    }

我必须看到这样的东西(但也许这不是个好主意?):

vector<string>::iterator board_elem;
vector<string>::iterator cell_itr;

for (board_elem = board.begin(); board_elem != board.end(); board_elem++) {
  for (cell_itr = board_elem.begin(); cell_itr != board_elem.end(); cell_itr++) {
    cout << board_elem[cell_itr];
  }
}
vector<vector<string> >::iterator board_elem = board.begin();

while (board_elem != board.end()) {
    vector<string>::iterator cell_itr = (*board_elem).begin();
    while (cell_itr != (*board_elem).end()) {
        cout << *cel_itr << '|';
        ++cel_itr;
    }
    cout << endl;
    ++board_elem;
}

如您所见,我将 board 设为字符串向量的向量。你写的方式根本没有任何意义。在您的示例中,board 迭代器将 return 一个字符串。在我的例子中,棋盘的每一行都是一个字符串向量。因此,棋盘迭代器 return 是一个字符串向量,它被写出,由“|”分隔。每行由换行符分隔。

如果板定义为

std::vector<std::string> board;

那么你可以使用

std::vector<std::string>::iterator board_elem;
std::string::iterator cell_itr;

for (board_elem = board.begin(); board_elem != board.end(); ++board_elem) 
{
    for (cell_itr = board_elem->begin(); cell_itr != board_elem->end(); ++cell_itr) 
    {
        // your code here using *cell_itr to get the character
    }
}

更好的方法是使用 C++11 并利用基于范围的 for 循环:

for (auto& row : board)
{
    for (auto& col : row)
    {
        // your code here using *col to get the character
    }
}

您可以尝试以下使用迭代器的方式:

vector<string>::iterator board_elem; // board is a vector of string
string::iterator cell_itr;

for (board_elem = board.begin(); board_elem != board.end(); ++board_elem) {
  for (cell_itr = board_elem->begin(); cell_itr != board_elem->end(); ++cell_itr) {
    if (*cell_itr=='*') {
        ++cell_itr;
        if (cell_itr != board_elem->end() && *cell_itr=='*') {
            sum += a;
        } else {
            sum += b;
            --cell_itr;
        }
    }
  }
}

假设 board 是一个字符串向量,那么我会使用 std::string 的搜索工具。可能是这样的:(未经测试的代码)

for ( auto iter = board.begin(); iter != board.end(); ++iter ) {
    std::string::size_type j = 0;
    while (j < iter->size() - 1) {
        if ((j = iter->find(start, "**")) == std::string::npos)
            break;
        // found a "**" at offset 'j'
        // do something here
        j++;
    }
}

您还可以使用 C++11 风格的 for 循环代替迭代器:

for ( const std::string &str : board ) {
    std::string::size_type j = 0;
    while ( j < str.size() - 1 ) {
        if ((j = str.find(start, "**")) == std::string::npos)
            break;
        // found a "**" at offset 'j'
        // do something here
        j++;
    }
}

我知道这并不是您问题的严格答案(How do I use iterators here),但是(恕我直言)这是解决您问题的更好方法。

总的来说,我看不出为什么你应该在这里使用迭代器,但如果你想:

for (auto bit = board.begin(); bit != board.end(); ++bit) {
    for (auto sit = bit->begin(); sit < bit->end(); ++sit) {
        if (*sit == '*') {
            if (*(++sit) == '*') {
                sum += a;
            } else {
                sum += b;
            }
        }
    }
}

如果您不能保证最后一个字符不是 '*',那么您必须将最后一个 if 替换为以下内容:

if ((cit+1) != it->end()  && *(++cit) == '*') { 

如果您想尝试一下,您也可以使用基于范围的 for 循环(尽管我不推荐它):

for (auto& e : board) {
    bool isFirst=true; //next * will be the first one in a row
    for (auto& c : e) {
        if (c == '*') {         
            sum += b;
            if (!isFirst) {
                sum = sum - 2*b + a; //second in a row - subtract what we falsely added             
            }   
            isFirst=!isFirst;           
        } else {
            isFirst = true;
        }
    }
}