C++ 有限列表中的简单选择
我有三个变量需要以某种方式设置。比如说,C++ 有限列表中的简单选择,c++,C++,我有三个变量需要以某种方式设置。比如说, int a, b, c; a = choose(1, 2, 3); // a can take the value 1 to 3 inclusive b = choose(1, 2, 3); // b can take the value 1 to 3 inclusive c = ?????? // c can't take either of the values in a or b. 设置c的最简单方法是使用循
int a, b, c;
a = choose(1, 2, 3); // a can take the value 1 to 3 inclusive
b = choose(1, 2, 3); // b can take the value 1 to 3 inclusive
c = ?????? // c can't take either of the values in a or b.
设置c的最简单方法是使用循环:
do
{
c = choose(1, 2, 3);
}
while(c == a || c == b);
或者,我可以使用ifs或开关,或开关/if组合:
a = choose(1, 2, 3);
b = choose(1, 2, 3);
switch(a){
case 1:
switch(b){
case 1:
c = choose(2, 3)
break;
case 2:
c = 3;
break;
case 3:
c = 2;
break;
}
break;
case 2:
…
这两个看起来都不优雅,而后者则是非常丑陋的
我在一个项目中遇到了类似的情况,我使用了有什么想法吗?一个简单的解决方案是将链接列表(通过引用)传递到
choose
函数中。选择的元素将从列表中删除并返回。对函数的后续调用将有越来越少的元素可供选择
您必须注意列表何时为空,并相应地进行处理
如果允许
a
和b
相同,则choose
将不是用于确定c
的函数。在这种情况下,可以使用一个单独的函数chooseC
,该函数获取所选值的列表(通过常量引用)和可用值的列表(通过值)。从可用值中删除所选值,然后从剩下的值中选择。可能是这样的:
int a, b, c;
int myList[]= {1, 2, 3};
a = choose(myList); // if choose can take a list as input
b = choose(myList);
myList.remove(a);
myList.remove(b);
c = choose(myList); // the selection from a and b are out of the list at this point
int choose(int, int); // two choice overload
int choose(int, int, int); // three choice overload
int main()
{
int c = choose(1, 2, 3);
int x = 1 + c % 3;
int y = 1 + (c + 1) % 3;
int a = choose(x, y);
int b = choose(x, y);
}
此解决方案确保
a != b && a != c
你可以认为这是你第二个解决方案的一个改进(优雅):
switch ((1<<a)|(1<<b))
{
case 2: // a,b == 1,1
c = choose(2,3);
break;
case 4: // a,b == 2,2
c = choose(1,3);
break;
case 6: // a,b == 1,2 or 2,1
c = 3;
break;
case 8: // a,b == 3,3
c = choose(1,2);
break;
case 10: // a,b == 1,3 or 3,1
c = 2;
break;
case 12: // a,b == 2,3 or 3,2
c = 1;
break;
}
开关((1Edit
第二种方法是,首先选择独特的元素,然后再选择其他两个元素,这样会更干净,尽管可能仍然不优雅
如果您坚持使用choose
的离散变量实现,它可能会如下所示:
int a, b, c;
int myList[]= {1, 2, 3};
a = choose(myList); // if choose can take a list as input
b = choose(myList);
myList.remove(a);
myList.remove(b);
c = choose(myList); // the selection from a and b are out of the list at this point
int choose(int, int); // two choice overload
int choose(int, int, int); // three choice overload
int main()
{
int c = choose(1, 2, 3);
int x = 1 + c % 3;
int y = 1 + (c + 1) % 3;
int a = choose(x, y);
int b = choose(x, y);
}
使用阵列更为简洁,只需稍加努力即可使其更加通用:
int choose(int[], int); // takes an array and its (effective) size
int main()
{
constexpr int maxNum = 3;
int choices[maxNum] = {1, 2, 3};
//for larger values of maxNum, loop initialize:
//for(int i = 0; i < maxNum; i++)
//{
// choices[i] = i + 1;
//}
int c = choose(choices, maxNum);
choices[c-1] = maxNum;
int a = choose(choices, maxNum - 1);
int b = choose(choices, maxNum - 1);
}
如果您真的需要确定性运行时的保证,您可以尝试下面的方法。但是,我不确定每个人都会觉得它更“优雅”,我认为维护性的损失是不值得的
if(a != b)
{
c = 6 - (a + b);
}
else
{
c = choose(0, 1);
c = 1 + (a + c) % 3;
}
考虑到这个问题是如何设置的,也没有那么大的可伸缩性,但在需要将其变得更一般之前,我假设。您真的只有3个这样的值,还是这是一个最小化的示例?
对于这种情况,我会直接排除所取的值
int a, b, c;
a = choose(1, 2, 3); // a can take the value 1 to 3 inclusive
b = choose(1, 2, 3); // b can take the value 1 to 3 inclusive
c = 1;
if(a == c || b == c)
c = 2;
if(a == c || b == c)
c = 3;
如果值为1,2,3,您可以用一个while循环来替换它,该循环与您的循环类似:
c = 1;
while(a == c || b == c)
c++;
如果需要选择c
,while循环对我来说似乎很好。我发现第一个循环很优雅。在choose
中添加可选值,将其从使用中删除?c=choose(1,2,3,a,b);
因此choose
接受固定数量的元素?@jerry@crashmstr the choose()函数此时实际上并不存在,但如果存在,它可能只是:returnrand()%3+1;
。我可以将choose作为变量编写,但由于它无法传递任何像std::list
这样的智能数据,但只能在数组上运行,因此它似乎没有帮助?@peedurr我认为变量函数太过分了。请注意,大多数答案都假设存在choose
,它可以提供不同数量的INPUT,虽然可能仍然是固定的。这可以通过重载或传入数组及其大小来实现,但考虑到您建议的实现的简单性质,您也可以轻松地直接调用rand
。说到这一点,rand()%3
,并不理想(尤其是因为听起来您是在受限环境中操作的),尽管它可能适合您的情况。即使假设choose
可以这样修改,似乎这并不是OP想要的。根据这个问题,a
和b
可能都有相同的值,所以为a
选择的任何内容都不应该从列表中删除。但是,我没有hink删除元素是正确的想法,特别是如果它要缩放的话。@jerry我刚刚在考虑这个问题。我假设choose
会使它们都是唯一的,但这可能不是他所要求的。我的解释基于注释//a可以取1到3的值,包括和//b可以接受包含1到3的值
,以及嵌套的开关
语句有一种情况,即a==1&&b==1
(因此c=choose(2,3)
)。@jerry同意。我还添加了一节描述如何处理这种情况。choose()
在这一点上是一个理论函数。我同意,如果可以传递一个std::list
或类似的函数,那么删除项就好了。但是,它只能传递内部类型。这当然可能包括一个链接列表,但这似乎太复杂了。我越想它,越看这里的回复,我就越开始了ng认为do
循环是最清晰、可读性最好的,如果不是此时的最佳解决方案的话。数组没有remove
方法。另外,choose
函数似乎没有在问题中使用数组。@jerry我不确定他有什么容器(1、2、3)除非选择只需要3个输入,否则可能需要一个数组而不是一个STD::在这种情况下,这个解决方案不会为我所用的“我不能在这里使用,而不得不使用一个更不太像STL和更老的学校C++解决方案”来表示“没有代码> STD< /COD>容器”。.choose
接受问题中的单个int
s,并且没有任何迹象表明OP的实际代码不同,所以这就是我的假设。虽然你可能是对的,但我理解这个问题意味着c
仍然应该以相同的概率接受所有值。显然,这些解决方案是错误的