我有一个非常简单的问题,我对实现该方法的方式非常困惑。我想在由三元语句组成的一行中创建一个布尔变量,例如:
boolean = a吗? b:(c?d:(e?f:(g?i:j);
出于我的代码的目的,它适用于1、2或3个这样的无条件条件,但是我编写它的方式是可以选择要相互定义的布尔三元条件数变量。
我坚持这样做,因为最后似乎无法添加最后一个条件。我试图考虑一个递归函数,也许带有一些计数器,但是我无法编写它。我不知道我问的是更简单还是清楚。
条件不是彼此完全独立的,存在以某种方式彼此遵循的间隔(空间坐标)。因此,例如,在我的示例中,“ a”将类似于11,然后当它为false并以新条件表示22时,它将继续。因此,我想引入一些计数器来放入条件。
但是,当我到达最后一个错误条件时,我不知道该怎么办,因为我无法建立随机的z>使我的代码正常工作的东西。
我正在尝试类似的事情:
bool f(double x, double value, double z, double d, double n, double step, int &count);{
bool result;
count++;
if (count == n) {return result}
result = (x >=value+count*step && x<value+(count+1)*step) ? z>=d : f(x,value,z,d,n,step, &count);
}
因此,当然,除了我编写递归函数的方式中可能存在很多错误之外,因为我从不使用它们,并且通常不使用C或C ++,这似乎表明在函数的最后一次调用中,我们将拥有像? b:如果语句为假,则不带最后一个参数。
我尽力保持清楚。如果您不明白这一点,可以提出问题。任何帮助都是受欢迎的,包括递归函数,普通函数或完全没有任何功能的方法...
最诚挚的问候,并预先感谢您的回答!
编辑:
带有if的代码应类似于:
if (a){
b}
else{
if (c){
d}
else{
if(e){
f}
else{
if(g){
I}
else{
j}
我可能忘记了一些括号,但我希望它是可以理解的。这一点是继续说n个if语句,在一行中创建一个布尔变量,然后每次我想添加一个if语句时都可以选择n而不是重写新代码。
编辑递归:
有人可以解释一下为什么这种函数会产生无限循环吗?
bool f(double x, double l, double z, double d, double step, int &count){
int n = (int)l/step;\\number of steps
count++;
if (count < n)
return (x >=l+count*step && x<l+(count+1)*step) ? z>=d*count : f(x,l,z,d,step,count);
else
return z>=d*(count-1);
}
在调用函数之前,我将计数器的“ count”设置为-1,这似乎是问题所在。它正确地执行了循环,但随后又一次又一次地重新启动,因此我什至无法检查我的代码是否对我的目的有意义。我以为每次返回以递归方式调用该函数后,它都会增加计数器,但是一旦到达n,它应该返回其他内容并退出该函数,而不是重新启动计数器并再次执行所有操作...
答案 0 :(得分:1)
要更清楚地写出if ... else if
阶梯,请去除括号并去除缩进。像这样:
if (a)
boolean = b;
else if (c)
boolean = d;
,依此类推。但我倾向于将其编写为函数:
if (a)
return b;
else if (c)
return d;
,依此类推。不过,如果您喜欢三元运算符,则可以按照易于阅读的规范方式进行编写:
boolean = a ? b
: c ? d
: e ? f
: g;
答案 1 :(得分:1)
[答案的第四版,考虑到评论]
在提供的第一个简单示例的特定情况下,可以编写可变参数函数。这里的模板... args参数指示可变数量的参数。可以调用f(false,false,true)或f(false,false,false,true,true)或更多参数。
bool ff(bool a, bool b, bool c) {
return a ? b : c;
}
template<class ...Args>
bool ff(bool a, bool b, Args ...args){
return a ? b : ff(args...);
}
如用户463035818所述,在第一次调用ff(。)函数(由main调用)时,如果可能在此拳头调用期间评估所有布尔值,则存在发生短路的风险。我不知道编译器的优化可能会发生内联和展开的情况,但是对编译器施加压力是没有用的。
无论如何我现在都知道步骤数是一个输入参数,可变参数模板函数似乎不适用。当然,可以使用类似于您提出的递归函数来解决它。但是,我认为,简单的“ for循环”既高效又灵活。 在我以前的回答中,我提出了一个基于for循环的解决方案。但是,由于它不符合您的需求,因为我误解了数学问题,因此将其删除。
相反,我回到您在帖子中提出的第二个递归函数。您问为什么递归没有完成。由于声誉欠佳,我无法直接发表评论。我不明白为什么程序没有停止,所以我实现了该程序,并且程序正常完成,但是结果似乎不正确。我看到有关参数 l 的问题。它似乎既对应于 x 的范围,又对应于 x 的最小值。我试图纠正它。我可能没有正确选择输入参数值。因此,我在下文中放置了相应的程序供您检查。
#include <iostream>
bool f(double x, double xmin, double range, double z, double d, double step, int &count){
int n = range/step; //number of steps
count++;
if (count < n) {
double a = xmin + count*step;
return ((x >=a) && (x< a + step)) ? z>=d*count : f(x,xmin,range,z,d,step,count);
} else
return z>=d*(count-1);
}
int main () {
int count = -1;
double xmin = 0.0;
double x = 2.0;
double range = 4.0;
double step = 1.0;
double d = 1.0;
double z = 2.0;
bool test = f (x, xmin, range, z, d, step, count);
std::cout << "test = " << test << "\n";
std::cout << "count = " << count << "\n";
return 0;
}
在这种特殊情况下,最好将 range 替换为 n 作为输入参数,以避免重复计算 n 。
答案 2 :(得分:0)
可读性与效率
关键是我不希望我的代码优美或可读,但高效。
老实说,我认为这不是一个好策略。低效的代码并不优雅。当然,这并不意味着可读代码是自动有效的。 但是,意外阻止编译器进行优化比推动它发出比已经执行的更好的代码要容易得多。可读的代码包含的错误更少,并可以帮助您避免明显的效率低下。话虽如此,...
为什么不编写可变参数条件函数?
除了可读性之外,还需要考虑另一件事:短路。使用普通条件
bool x = condition ? t : some_other_function_call();
如果condition
是true
,则在
some_other_function_call()
不会被评估
bool x = foo(t,some_other_function_call());
在任何一种情况下都会调用另一个函数。您无法通过foo
短路。
该怎么做?
Pete Becker的答案很好地演示了如何以一种简洁的方式编写条件(最重要的是,当案例相互排斥时,您无需嵌套它们(它们是三元的!))。
无论如何...如何编写可变条件函数?
仅出于完整性考虑,这就是您可以编写这样的函数以用函数调用替换bool x = a ? b : (c ? d : (e ? f : (g ? i : j );
的功能(请不要使用):
// DISCLAIMER: DONT DO THIS
bool my_conditional(std::vector<bool> x){
if (x.size() == 1) return *x.begin();
bool condition = *x.begin();
bool true_value = *(x.begin()+1);
return condition ? true_value : my_ternary({x.begin()+2,x.end()});
}
您可以这样称呼它:
my_conditional({ condition1, true_value1, condition2, true_value2, false_value});
例如
std::cout << my_conditional({false,false,false,false,false});
打印0
。