按索引对数组进行分区
Partitioning arrays by index
我对c++相当陌生,我正在努力解决一个问题,似乎有一个坚实的解决方案,但我似乎找不到它。我有一个连续的整数数组,从0开始:
int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator
我想把数组分成三组。设计是有两个方法,j
和k
,这样,给定一个i
,它们将返回同一组三个元素中的另外两个元素。例如:
解决方案似乎涉及将i
与其值mod 3和正负1相加,但我似乎无法完全解决逻辑。
应该可以:
int d = i % 3;
int j = i - d + ( d == 0 );
int k = i - d + 2 - ( d == 2 );
或后面的语句对于k可以更具可读性:
int k = i - d + ( d == 2 ? 1 : 2 );
应该这样做:
int j(int i)
{
int div = i / 3;
if (i%3 != 0)
return 3*div;
else
return 3*div+1;
}
int k(int i)
{
int div = i / 3;
if (i%3 != 2)
return 3*div+2;
else
return 3*div+1;
}
测试。
如果你想要更短的函数:
int j(int i)
{
return i/3*3 + (i%3 ? 0 : 1);
}
int k(int i)
{
return i/3*3 + (i%3-2 ? 2 : 1);
}
首先,注意
j(i) == j(3+i) == j(6+i) == j(9+i) == ...
k(i) == k(3+i) == k(6+i) == k(9+i) == ...
换句话说,你只需要为
找到一个公式j(i), i = 0, 1, 2
k(i), i = 0, 1, 2
,然后在其他情况下只需插入i mod 3
。
从那里,你将很难找到一个简单的公式,因为你的"旋转"不是标准的。而不是
i j(i) k(i)
0 1 2
1 2 0
2 0 1
对应的公式应该是
j(i) = (i + 1) % 3
k(i) = (i + 2) % 3
你有i j(i) k(i)
0 1 2
1 0 1
2 0 2
目前我能想到的唯一公式是
j(i) = (i == 0 ? 1 : 0)
k(i) = (i == 1 ? 1 : 2)
如果数组的值(我们称其为arr
,而不是i
,以避免与索引i
混淆)与它们各自的索引不一致,则必须首先执行反向查找以找出它们的索引。我建议使用std::map<int,size_t>
或std::unordered_map<int,size_t>
。
该结构体反映了arr
的逆,您可以使用下标操作符或at
成员函数为特定值添加索引。从那时起,您可以纯粹对索引进行操作,并使用模(%
)来访问其他答案中建议的前一个和下一个元素。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '