创建索引数组的标准库函数,其对应值为给定数字
Standard library function to create array of indices whose corresponding value is a given number
我有一个名为 board
的 C 风格数组,其中包含一些 char
。我正在尝试创建一个 std::array
或 std::vector
(两者都可以,尽管 std::array
更可取)来存储 board
的所有具有特定值的索引(就我而言,0
)。
我写的这段代码很实用,运行良好:
std::vector<int> zeroes;
zeroes.reserve(16);
//board has 16 elements, so zeroes.size() will never be larger than 16.
//I used this reserve for speedup - the compiler doesn't require it.
for (int i = 0; i < 16; ++i)
{
if (board[i] == 0)
{
zeroes.push_back(i);
}
}
但是,根据过去的经验,只要存在可以替换我的部分代码的 std
函数,它就会更简洁,因此在风格上更受欢迎,而且速度更快。我的函数似乎是一个相当基本的操作——我知道有一个标准函数*可以访问一个数组的索引,该数组包含一个值,当该值在数组中只出现一次**时。那么,假设存在多个这样的索引,是否有一个标准函数可以创建包含一个值的索引数组?
* 从技术上讲,两个嵌套函数调用:int x = std::distance(board, std::find(board, board + 16, 0));
。参见 the accepted answer here。
** 好吧,如果存在多个具有所需值的索引,它仍然有效,但它 returns 只是第一个这样的索引,这在我的上下文中不是很有用。
编辑:
由于其中一个答案误解了这个问题,我会澄清我在寻找什么。假设我们有:
char board[16] = {0, 2, 0, 4,
2, 4, 8, 2,
0, 0, 8, 4,
2, 0, 0, 2};
现在,我正在寻找的索引是 {0, 2, 8, 9, 13, 14}
因为 board[0] = 0
、board[2] = 0
、board[8] = 0
等,这些是唯一满足的数字属性.
这是使用 std::iota
和 std::remove_if
的解决方案:
#include <algorithm>
#include <iostream>
int main () {
const std::size_t board_size = 16;
char board [board_size] = {
0, 2, 0, 4,
2, 4, 8, 2,
0, 0, 8, 4,
2, 0, 0, 2
};
// Initialize a zero-filled vector of the appropriate size.
std::vector<int> zeroes(board_size);
// Fill the vector with index values (0 through board_size - 1).
std::iota(zeroes.begin(), zeroes.end(), 0);
// Remove the index values that do not correspond to zero elements in the board.
zeroes.erase(std::remove_if(zeroes.begin(), zeroes.end(), [&board] (int i) {
return board[i] != 0;
}), zeroes.end());
// Output the resulting contents of the vector.
for (int i : zeroes) {
std::cout << i << std::endl;
}
}
程序输出(demo):
0
2
8
9
13
14
我有一个名为 board
的 C 风格数组,其中包含一些 char
。我正在尝试创建一个 std::array
或 std::vector
(两者都可以,尽管 std::array
更可取)来存储 board
的所有具有特定值的索引(就我而言,0
)。
我写的这段代码很实用,运行良好:
std::vector<int> zeroes;
zeroes.reserve(16);
//board has 16 elements, so zeroes.size() will never be larger than 16.
//I used this reserve for speedup - the compiler doesn't require it.
for (int i = 0; i < 16; ++i)
{
if (board[i] == 0)
{
zeroes.push_back(i);
}
}
但是,根据过去的经验,只要存在可以替换我的部分代码的 std
函数,它就会更简洁,因此在风格上更受欢迎,而且速度更快。我的函数似乎是一个相当基本的操作——我知道有一个标准函数*可以访问一个数组的索引,该数组包含一个值,当该值在数组中只出现一次**时。那么,假设存在多个这样的索引,是否有一个标准函数可以创建包含一个值的索引数组?
* 从技术上讲,两个嵌套函数调用:int x = std::distance(board, std::find(board, board + 16, 0));
。参见 the accepted answer here。
** 好吧,如果存在多个具有所需值的索引,它仍然有效,但它 returns 只是第一个这样的索引,这在我的上下文中不是很有用。
编辑: 由于其中一个答案误解了这个问题,我会澄清我在寻找什么。假设我们有:
char board[16] = {0, 2, 0, 4,
2, 4, 8, 2,
0, 0, 8, 4,
2, 0, 0, 2};
现在,我正在寻找的索引是 {0, 2, 8, 9, 13, 14}
因为 board[0] = 0
、board[2] = 0
、board[8] = 0
等,这些是唯一满足的数字属性.
这是使用 std::iota
和 std::remove_if
的解决方案:
#include <algorithm>
#include <iostream>
int main () {
const std::size_t board_size = 16;
char board [board_size] = {
0, 2, 0, 4,
2, 4, 8, 2,
0, 0, 8, 4,
2, 0, 0, 2
};
// Initialize a zero-filled vector of the appropriate size.
std::vector<int> zeroes(board_size);
// Fill the vector with index values (0 through board_size - 1).
std::iota(zeroes.begin(), zeroes.end(), 0);
// Remove the index values that do not correspond to zero elements in the board.
zeroes.erase(std::remove_if(zeroes.begin(), zeroes.end(), [&board] (int i) {
return board[i] != 0;
}), zeroes.end());
// Output the resulting contents of the vector.
for (int i : zeroes) {
std::cout << i << std::endl;
}
}
程序输出(demo):
0
2
8
9
13
14