[英]C++. Logical expression
I am trying to solve the following task.我正在尝试解决以下任务。 Given an integer x, I want to compute 2 numbers (a and b) which are:给定一个 integer x,我想计算 2 个数字(a 和 b),它们是:
I wrote the following code, to find such a and b.我写了下面的代码,找到了这样的a和b。
cin >> x;
if (x % 2 == 0) {
a = b = x / 2;
} else {
a = x / 2;
b = a + 1;
}
while((a % 3 !=0 || a % 2 != 0) && (b % 2 != 0 || b % 3 != 0)) {
a++;
b--;
}
However it does not work.但是它不起作用。 For example when x is 13, it prints out that a = 6 and b = 7. But 7 is not divisible by 2 or 3. What is the problem?例如,当 x 为 13 时,它打印出 a = 6 和 b = 7。但是 7 不能被 2 或 3 整除。有什么问题?
Examine your continuation condition carefully (where n
is some arbitrary integer, possibly different in each use so, for example a != 3n
simply means that a
is not a multiple of three).仔细检查您的延续条件(其中n
是任意的 integer,每次使用可能不同,例如a != 3n
仅表示a
不是三的倍数)。 I'll show the process:我将展示这个过程:
while((a % 3 != 0 || a % 2 != 0) && (b % 2 != 0 || b % 3 != 0))
( a != 3n OR a != 2n ) AND ( b != 2n OR b != 3n )
( a != 6n ) AND ( b != 6n )
It says: continue while both a
is not a multiple of both two and three, and b
is not a multiple of both two and three.它说:当a
不是 2和3 的倍数且b
不是 2和3 的倍数时继续。 In other words, it will only continue if both a
and b
are multiples of six.换句话说,只有当a
和b
都是 6 的倍数时,它才会继续。 On the flip side of that, it will of course exit if either a
or b
is not a multiple of six.另一方面,如果a
或b
不是 6 的倍数,它当然会退出。
Since an input value of 13
sets a = 6
and b = 7
, the continuation case is false on the first iteration (seven is not a multiple of six).由于输入值13
设置a = 6
和b = 7
,因此在第一次迭代时延续情况为假(七不是六的倍数)。
Perhaps it would be better to rethink the way you figure out whether certain number combinations are valid (a) .也许最好重新考虑确定某些数字组合是否有效的方式(a) 。 For example (assuming the numbers have to be between 1
and N - 1
since, otherwise, your solution space is likely to be infinite), you could use something like:例如(假设数字必须介于1
和N - 1
之间,否则,您的解决方案空间可能是无限的),您可以使用以下内容:
#include <iostream>
int main() {
// Get the number.
int num;
std::cout << "Number? ";
std::cin >> num;
// Check all i + j = n for 1 <= i,j < n.
for (int i = 1, j = num - 1; i < j; ++i, --j) {
// Disregard if either number not a multiple of 2 or 3.
if ((i % 2) != 0 && (i % 3) != 0) continue;
if ((j % 2) != 0 && (j % 3) != 0) continue;
std::cout << num << " => " << i << ", " << j << "\n";
return 0;
}
std::cout << num << " => no solution\n";
return 0;
}
Note my use of i < j
is the for
continuation condition, this is assuming they have to be distinct numbers.请注意,我对i < j
的使用是for
continuation 条件,这是假设它们必须是不同的数字。 If they're allowed to be the same number, change that to i <= j
.如果允许它们是相同的数字,请将其更改为i <= j
。
(a) Using all of and
, or
, and not
(even implicitly, by the reversal of continuation and exit conditions), is sometimes more trouble than it's worth since De Morgan's theorems tend to come into play: (a)使用所有的and
, or
, and not
(甚至隐含地,通过反转继续和退出条件),有时比它的价值更麻烦,因为 De Morgan 的定理往往会发挥作用:
_____ _ _
A ∩ B ⇔ A ∪ B : (not(A and B)) is ((not A) or (not B))
_____ _ _
A ∪ B ⇔ A ∩ B : (not(A or B)) is ((not A) and (not B))
In cases like that, code can become more readable if you break out the individual checks.在这种情况下,如果您打破个别检查,代码会变得更具可读性。
Interestingly, if you run that code with quite a few input values, you'll see the pattern that, if a solution exists, one of the numbers in that solution is always two or three.有趣的是,如果您使用相当多的输入值运行该代码,您会看到这样的模式:如果存在解决方案,则该解决方案中的一个数字始终是 2 或 3。
That's because, other than the pathological cases of sums less than five (or less than four if the solution is allowed to have identical numbers):这是因为,除了总和小于 5 的病理情况(或者如果允许解决方案具有相同的数字,则小于 4):
2n, n > 1
is the sum of 2
and 2n - 2
, both multiples of two ( 2n - 2 = 2(n - 1)
);每个偶数2n, n > 1
是2
和2n - 2
的总和,都是 2 的倍数 ( 2n - 2 = 2(n - 1)
); and和2n + 1, n > 2
is the sum of 3
and 2n + 1 - 3
, the first a multiple of three and the second a multiple of two ( 2n + 1 - 3 = 2n - 2 = 2(n - 1)
).每个奇数2n + 1, n > 2
是3
和2n + 1 - 3
的和,第一个是三的倍数,第二个是二的倍数 ( 2n + 1 - 3 = 2n - 2 = 2(n - 1)
)。So, in reality, no loop is required:所以,实际上,不需要循环:
if (num < 5) { // 4 if allowing duplicates.
std::cout << num << " => no solution\n";
} else {
int first = (num % 2) == 0 ? 2 : 3;
std::cout << num << " => " << first << ", " << (num - first) << "\n";
}
This actually gives a different result for some numbers, such as 17 = 2 + 15 = 3 + 14
but both solutions are still correct.这实际上对某些数字给出了不同的结果,例如17 = 2 + 15 = 3 + 14
但两种解决方案仍然正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.