我想比较两个正整数,并在它们之间添加一个比较符号。我不能使用任何logical
,relational
或bitwise operators
和if
,然后else
或while
循环或三元运算符。
我找到了这两个数字的max
和min
。
如何保留订单并仍然插入比较符号?有任何想法吗?
E.g:
用户输出输入的 4 6
必须为4 < 6
10 2
必须为10 > 2
2 2
必须为2 = 2
f1 = x / y;
f2 = y / x;
f1 = (f1 + 2) % (f1 + 1);
f2 = (f2 + 2) % (f2 + 1);
max = f1 * x + f2 * y ;
max = max / (f1 + f2);
答案 0 :(得分:5)
您可以使用char数组:
#include <stdio.h>
int main(void)
{
unsigned a, b;
scanf("%u %u", &a, &b);
size_t cmp = (_Bool)(a / b) - (_Bool)(b / a);
char relation = "<=>"[cmp + 1];
printf("%u %c %u\n", a, relation, b);
return 0;
}
此方法不需要min
和max
。
(_Bool)exp
非零,则exp
将为1;如果exp
等于0,则<0>。{/ li>
a
和b
是正整数,a / b
在a < b
时为0,在a >= b
时为1。有关详细信息,请参阅下面的真值表。(_Bool)(a / b) (_Bool)(b / a) (_Bool)(a / b) - (_Bool)(b / a) a > b 1 0 1 a = b 1 1 0 a < b 0 1 -1
cmp
评估为-1, 0, 1
,就像典型的比较函数一样。因此,cmp + 1
将方便地导致0, 1, 2
有效的数组索引。感谢@janos his help。
正如@chux小心指出的那样,
OP表示“我可能不使用任何逻辑,...运算符”。 C规范有 “......逻辑否定运算符!......”。 §6.5.3.35。使用!不得 符合OP的目标。
所以我将!!exp
更改为(_Bool)exp
以满足OP的要求。
感谢。当其中一个输入为0时,这不起作用。
但是,输入数字不是正面的吗?好吧,要处理零,您可以使用size_t cmp = (_Bool)((a + (_Bool)(a - UINT_MAX)) / (b + (_Bool)(b - UINT_MAX))) - (_Bool)((b + (_Bool)(b - UINT_MAX)) / (a + (_Bool)(a - UINT_MAX)));
。不要忘记#include <limits.h>
。
#include <stdio.h>
#include <limits.h>
#define ISEQUAL(x, y) (_Bool)((_Bool)((x) - (y)) - 1) // 1 if x == y, 0 if x != y
#define NOTEQUAL(x, y) (_Bool)((x) - (y)) // 0 if x == y, 1 if x != y
int main(void)
{
unsigned a, b;
printf("%u\n", UINT_MAX);
scanf("%u %u", &a, &b);
_Bool hasZero = NOTEQUAL(ISEQUAL(a, 0) + ISEQUAL(b, 0), 0);
_Bool hasMax = NOTEQUAL(ISEQUAL(a, UINT_MAX) + ISEQUAL(b, UINT_MAX), 0);
int hasBoth = ISEQUAL(hasZero + hasMax, 2);
int cmp = (_Bool)((a + hasZero + hasBoth) / (b + hasZero + hasBoth))\
- (_Bool)((b + hasZero + hasBoth) / (a + hasZero + hasBoth));
// "+ hasZero + hasBoth" to avoid div 0: UINT_MAX -> 1, while 0 -> 2.
hasBoth = 1 - hasBoth * 2; // 1 if hasBoth == 0, or -1 if hasBoth == 1
char relation = "<=>"[hasBoth * cmp + 1]; // reverse if has both 0 and UINT_MAX
printf("%u %c %u\n", a, relation, b);
return 0;
}
答案 1 :(得分:4)
由于OP有x
,y
并已计算出其最低min
和最高max
void prt(unsigned x, unsigned y, unsigned min, unsigned max) {
// min not used
unsigned cmp = 1 + x/max - y/max;
printf("%u %c %u\n", x, "<=>"[cmp], y);
}
答案 2 :(得分:1)
#include <stdio.h>
static unsigned int cmpgt(const unsigned int a, const unsigned int b)
{
return b?(a/b ? (a-b):0):a;
// if B is 0, then return A. non zero A will be treated as true
// if a is zero then is false
// if b is not zero then do a/b, if non zero then return (a-b)
// non zero (a-b) will be treated as true
// if (a-b) is zero then will be treated as false
//
// This is a very ugly way of implementing operator >
// There are other ways to do it
// But the point is, you need operator >, but you can not use it
// ( for whatever reason), then you just make it, which is doable
}
static const char *mark(const unsigned int a, const unsigned int b)
{
return cmpgt(a, b)?">":(cmpgt(b,a)?"<":"=");
// no if-else, but ternary operator is a good alternative
// so those are two nested operator ?:
// basically :
// if a>b then return ">"
// else if a<b return "<"
// else return "="
// with cmpgt/operator > implemented, this is a lot easier
}
int main(void) {
const int input[] = {1,3,4,5,5,2,3,4}; //test input
size_t input_size = sizeof(input)/sizeof(int);
for (size_t i=0;cmpgt(input_size-1, i);i++){
// while loop is banned, but for loop is still usable
// the loop condition is handled by cmpgt
printf("%d %s ",input[i],mark(input[i], input[i+1]));
}
printf("%d\n", input[input_size-1]);
return 0;
}
示例输出:
1 < 3 < 4 < 5 = 5 > 2 < 3 < 4
答案 3 :(得分:0)
一个简单的比较是使用<=
,>=
,然后从字符串中查找比较字符。
void cmp1(unsigned x, unsigned y) {
int cmp = (x >= y) - (x <= y);
printf("%u %c %u\n", x, "<=>"[cmp + 1], y);
}
然而,由于我们不能使用各种运算符等,我们需要做的就是替换>=
。
_Bool foo_ge(unsigned x, unsigned y) {
_Bool yeq0 = 1 - (_Bool)y; // y == 0?
_Bool q = (x + yeq0)/(y + yeq0); // Offset both x,y, by yeq0
return q + yeq0;
}
void cmp2(unsigned x, unsigned y) {
int cmp = foo_ge(x,y) - foo_ge(y,x)
printf("%u %c %u\n", x, "<=>"[cmp + 1], y);
}
大量使用_Bool
赠送给@sun qingyao