C语言 最大和最小的四个整数(没有数组,没有函数,最少的“if”语句)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19199473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Biggest and smallest of four integers (No arrays, no functions, fewest 'if' statements)
提问by MegamanEXE
You see, I've self-taught myself C++ (not completely, I'm still procrastinating -_-). So, now I started university and they're teaching C and they made us do a program of inputting four integers and we have to tell the largest and smallest out of them. Simple, no?
你看,我自学了 C++(不完全,我还在拖延-_-)。所以,现在我开始上大学,他们在教 C,他们让我们做一个输入四个整数的程序,我们必须从中分辨出最大和最小的。简单,不是吗?
The thing is, I already have good understanding of functions and arrays. Yes, I CAN program this in arrays, no problem. But since this was the first lab, we haven't 'learned' that yet, so I can't use any of those, it'd be very simple with that.
问题是,我已经对函数和数组有了很好的理解。是的,我可以在数组中编程,没问题。但是因为这是第一个实验室,我们还没有“学习”,所以我不能使用任何一个,这很简单。
This is what I wrote there (it feels wrong somehow).
这就是我在那里写的(不知何故感觉不对)。
#include<stdio.h>
int main(void)
{
int first, second, third, fourth;
printf("Enter four integers (separated by space): ");
scanf("%d %d %d %d", &first, &second, &third, &fourth);
if((first>second) && (first>third) && (first>fourth))
printf("\nFirst number is largest");
else if((second>first) && (second>third) && (second>fourth))
printf("\nSecond number is largest");
else if((third>second) && (third>first) && (third>fourth))
printf("\nThird number is largest");
else if((fourth>second) && (fourth>third) && (fourth>first))
printf("\nFourth number is largest");
if((first<second) && (first<third) && (first<fourth))
printf("\nFirst number is smallest");
else if((second<first) && (second<third) && (second<fourth))
printf("\nSecond number is smallest");
else if((third<second) && (third<first) && (third<fourth))
printf("\nThird number is smallest");
else if((fourth<second) && (fourth<third) && (fourth<first))
printf("\nFourth number is smallest");
printf("\n");
return 0;
}
As you can see, it's too long and boring and complex. But seeing that all we've covered in class for now are loopsand decision statements. Is there a more elegant way of doing this? One which uses fewer ifs? Not that there is something wrong with this, but it could be better.
如您所见,它太长、太无聊且太复杂。但是看到我们现在在课堂上介绍的都是循环和决策语句。有没有更优雅的方法来做到这一点?一个使用较少的ifs?并不是说这有什么问题,但它可能会更好。
P.S. This isn't exactly 'homework' or anything. I made a program, I just wanted to know what I could have done to make it better and to learn better programming practices.
PS 这不完全是“家庭作业”或任何东西。我做了一个程序,我只是想知道我可以做些什么来让它变得更好并学习更好的编程实践。
回答by haccks
As per the OP's condition
根据OP的条件
But seeing that all we've covered in class for now are loopsand decision statements. Is there a more elegant way of doing this? One which uses fewer
ifs?
但是看到我们现在在课堂上介绍的都是循环和决策语句。有没有更优雅的方法来做到这一点?一个使用较少的
ifs?
Only one ifand one else ifstatement and one forloop can do this task. Simple and short!
只有一个if和一个else if语句和一个for循环才能完成这项任务。简单又短!
#include <stdio.h>
int main()
{
int num, max, min;
printf ("Enter four numbers: ");
scanf ("%d", &num);
max = min = num;
for (int i = 0; i < 3; i++)
{
scanf ("%d", &num);
if (max < num)
max = num;
else if (min > num)
min = num;
}
printf ("The smallest and largest of given four numbers are %d and %d respectively.\n", min, max);
return 0;
}
回答by m01
Do a "manual" merge sort, or well, just the second bit of it:
做一个“手动”合并排序,或者好吧,只是它的第二位:
Conceptually, a merge sort works as follows
- Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element is considered sorted).
- Repeatedly merge sublists to produce new sublists until there is only 1 sublist remaining. This will be the sorted list.
从概念上讲,归并排序的工作原理如下
- 将未排序的列表分成 n 个子列表,每个子列表包含 1 个元素(1 个元素的列表被视为已排序)。
- 重复合并子列表以产生新的子列表,直到只剩下 1 个子列表。这将是排序列表。


Code:
代码:
int a = 5, b=4, c=7, d=9;
int min_ab, min_cd, min;
min_ab = a < b ? a : b;
min_cd = c < d ? c : d;
min = min_ab < min_cd ? min_ab : min_cd;
printf("%d", min);
.. and similarly for max.
.. 和最大值类似。
If you prefer, you can expand the ternary operator into if (a < b) { min_ab = a; } else { min_ab = b; }(spread over multiple lines for readability).
如果您愿意,可以将三元运算符扩展为if (a < b) { min_ab = a; } else { min_ab = b; }(扩展到多行以提高可读性)。
Merge sort has a complexity of O(n*log(n)), so you should at most need O(n*log(n))ifs (see the wikipedia article on merge sort). According to Wikipedia, "... These are all comparison sorts, and so cannot perform better than O(n log n) in the average or worst case" (source), so I think this shouldn't be too far off in terms of minimum number of ifs.. Though you could try to see if manually performing one of the other algorithms results in fewer ifs ;-).
合并排序的复杂度为O(n*log(n)),因此您最多应该需要O(n*log(n))ifs(请参阅关于合并排序的维基百科文章)。根据维基百科,“......这些都是比较排序,因此在平均或最坏情况下不能比 O(n log n) 表现得更好”(来源),所以我认为这不应该太远ifs的最小数量。尽管您可以尝试查看手动执行其他算法之一是否会导致ifs减少;-)。
回答by Arpit
回答by AnT
The whole point of the classroom problem that requests finding the largest and the smallest simultaneouslyis to teach you to extract maximum valuable information from each comparison.
课堂问题的整点,找到最大和最小的请求,同时是教你提取每个比较最大的有价值的信息。
For example, if you know that a > bis true, from that single comparison you should realize that ais no longer candidate for the smallest and should no longer participate in any comparisons dedicated to finding the smallest. And, at the same time, you should realize that bis no longer candidate for the largest. With 4 numbers, two tests a > band c > dalready clearly separate the numbers into two independent classes: two candidates for the largest and two candidates for the smallest. The rest is straightforward.
例如,如果您知道这a > b是真的,那么从该单个比较中您应该意识到它a不再是最小的候选,并且不应再参与任何专门寻找最小的比较。而且,与此同时,您应该意识到,这b不再是最大的候选人。有 4 个数字,两次测试a > b并且c > d已经清楚地将数字分成两个独立的类别:最大的两个候选和最小的两个候选。其余的很简单。
In other words, the whole idea is to find the extreme values in parallel, using the information provided by each comparison to further the task of finding boththe smallest and the largest value.
换句话说,整个构思是要找到极值并行,利用各自的比较提供的信息来发现进一步的任务都最小和最大的价值。
if (first > second) {
int t = first; first = second; second = t;
}
if (third > fourth) {
int t = third; third = fourth; fourth = t;
}
/* Now 'first' and 'third' are candidates for the smallest,
while 'second' and 'fourth' are candidates for the largest */
int min = first < third ? first : third;
int max = second > fourth ? second : fourth;
As you can see, this requires only four comparisons to find both numbers.
如您所见,这只需进行四次比较即可找到两个数字。
Note that the above code gives you the valuesof the smallest and the largest, but it does not tell you the original "index" of the number that provided each value. It is not immediately clear whether it is really necessary. The text of your question says nothing about that, while the code sample you provided implements it. In any case, it is not difficult to update the above code to make it to "track" the origins of the numbers.
请注意,上面的代码为您提供了最小和最大的值,但它没有告诉您提供每个值的数字的原始“索引”。目前还不清楚是否真的有必要。您的问题的文本没有说明这一点,而您提供的代码示例实现了它。无论如何,更新上面的代码以使其“跟踪”数字的起源并不困难。
回答by Ingo
This is too easy, given that the numbers are a,b,c,d:
鉴于数字是 a,b,c,d,这太容易了:
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
biggest = max (max(a,b), max(c,d))
smallest = min (min(a,b), min(c,d))
Here you go, no if statements, no functions (though the latter is the most stupid and harmful to adepts requirement I ever heard of).
在这里,没有 if 语句,没有函数(尽管后者是我听说过的最愚蠢和最有害的专家要求)。
回答by Pieter Geerkens
Here is a solution with no if or elseif or function or macro, but using bit-shift and subtraction instead; only using a single forloop:
这是一个没有 if 或 elseif 或 function 或 macro的解决方案,而是使用位移和减法;只使用一个for循环:
#include <stdio.h>
int main(){
int num , max, min;
printf("Enter four numbers: ");
scanf("%d", &num);
max = min = num;
for(int i = 0; i < 3; i++)
{
scanf("%d", &num);
max = max * (1 - ( (max-num) >> 31) )
+ num * ( (max-num) >> 31);
min = min * (1 - ( (num-min) >> 31) )
+ num * ( (num-min) >> 31);
}
printf("\n%d %d", max, min);
return 0;
}
The (max-num) >> 31)operation captures the sign of the difference, which when multiplied by the second number yields the minimum value of the comparison.
该(max-num) >> 31)操作捕获差的符号,当乘以第二个数字时产生比较的最小值。
This comes from an old SQLcoding trick from the days before there was a CASE WHENconstruct in that language.
这来自在该语言中存在CASE WHEN构造之前的旧SQL编码技巧。
回答by Suman Saurabh
Try this
尝试这个
int max_of_four(int a,int b,int c,int d){
int max=a;
if(b>max) max=b;
if(c>max) max=c;
if(d>max) max=d;
return max;
}
without if would be like this
没有如果会是这样
int max_of_four(int a, int b, int c, int d) {
return ((a > b && a > c && a > d) ? a: ((b > c && b > d) ? b : (c > d ? c : d)));
}
回答by Nishwal Shetty
int max(int a, int b) {
return a > b ? a : b;
}
int max_of_four(int a, int b, int c, int d) {
return max(a, max(b, max(c, d)));
}
int main() {
int a, b, c, d;
scanf("%d %d %d %d", &a, &b, &c, &d);
int ans = max_of_four(a, b, c, d);
printf("%d", ans);
return 0;
}
回答by Daniel Martín
One idea may be to compute the maximum and minimum of the first two numbers. Then, you compare the rest of the numbers in pairs. The greater one of each pair is compared against the current maximum, and the smaller one of each pair is compared against the current minimum. This way you do 3 comparisons for every 2 elements, which is slightly more efficient than Arpit's answer (2 comparisons for each element).
一种想法可能是计算前两个数字的最大值和最小值。然后,您成对比较其余的数字。每对中较大的一个与当前最大值进行比较,而每对中较小的一个与当前最小值进行比较。通过这种方式,您对每 2 个元素进行 3 次比较,这比 Arpit 的答案(每个元素进行 2 次比较)效率更高。
In code:
在代码中:
#include <stdio.h>
int main(int argc, char **argv) {
int a, b, c, d;
printf("Enter four integers (separated by space): ");
scanf("%d %d %d %d", &a, &b, &c, &d);
int max, min;
if (a > b) {
max = a;
min = b;
}
else {
max = b;
min = a;
}
if (c > d) {
if (c > max) {
max = c;
}
if (d < min) {
min = d;
}
}
else {
if (d > max) {
max = d;
}
if (c < min) {
min = c;
}
}
printf("max = %d, min = %d\n", max, min);
return 0;
}
回答by motu
This is C code has only 4 if statements. It moves max number to d position and min number to a position. Values b and c are not properly arranged within a sequence, but since requirements ask for min and max this code completes a job:
这是 C 代码只有 4 个 if 语句。它将最大数量移动到 d 位置,将最小数量移动到一个位置。值 b 和 c 在序列中没有正确排列,但由于要求要求 min 和 max,此代码完成了一项工作:
#include <stdio.h>
int main() {
int a, b, c, d, temp;
printf("Enter four digits: ");
scanf("%d %d %d %d", &a, &b, &c, &d);
if ( a > b){
temp = a; a = b ; b = temp;
}
if ( c > d){
temp = c; c = d ; d = temp;
}
if ( b > d ){
temp = b; b = d; d = temp;
}
if ( a > c){
temp = a; a = c ; c = temp;
}
printf("Max %d\nMin %d\n", d, a);
return 0;
}

