0

我对 C++ 相当陌生,并且正在努力解决一个似乎有可靠解决方案但我似乎无法找到它的问题。我有一个从零开始的连续整数数组:

int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator

我想将数组分成三组。设计是有两个方法jk,这样给定一个i它们将返回来自同一组的三个元素的其他两个元素。例如:


ij(i) k(i)  
0 1 2  
1 0 2  
2 0 1  
3 4 5  
4 3 5  
5 3 4  

解决方案似乎涉及将i与它的值 mod 3 和加或减 1 相加,但我似乎不太能弄清楚逻辑。

4

4 回答 4

1

这应该这样做:

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);
}
于 2013-03-05T21:12:01.833 回答
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 );
于 2013-03-05T21:15:04.297 回答
0

嗯,首先,请注意

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)
于 2013-03-05T21:11:42.293 回答
0

如果您的数组的值(我们称之为它arr,不是i为了避免与索引混淆i)与它们各自的索引不一致,您必须先执行反向查找以找出它们的索引。我建议使用一个std::map<int,size_t>或一个std::unordered_map<int,size_t>

该结构反映了的倒数,您可以使用其下标运算符或成员函数arr为特定值添加索引。从那时起,您可以纯粹对索引进行操作,并按照其他答案中的建议使用模 ( ) 访问上一个和下一个元素。at%

于 2013-03-05T21:23:19.693 回答