我的升序排序问题是一个好的解决方案吗?

问题描述

#include <iostream>
using namespace std;

int main() {
// Problem #2 Ascending Order
int num1,num2,num3,small,medium,large;
cin >> num1 >> num2 >> num3;

if(num1 <= num2 && num1 <= num3) {
    small = num1;
    if(num2 <= num3) {
        medium = num2;
        large = num3;
    } else {
        large = num2;
        medium = num3;
    }
} else if(num2 <= num1 && num2 <= num3) {
    small = num2;
    if(num3 <= num1) {
        medium = num3;
        large = num1;
    } else {
        large = num3;
        medium = num1;
    }
} else {
    small = num3;
    if(num2 <= num1) {
        medium = num2;
        large = num1;
    } else {
        large = num2;
        medium = num1;
    }
}

cout << small << " " << medium << " " << large;
return 0;

/* 这段代码是对3个数字进行升序排序,这是我想到的解决方案。 我不确定这是否是一个好的答案,他们有没有更好的方法来做到这一点?我应该对此感到高兴吗 解决方案?有什么想法吗?我是编程新手,想知道我提出的解决方案是否是 现实?如果我像这样解决问题,他们是否足以让我找到工作?这是否显示 我是一个糟糕的程序员? */

解决方法

没有。你的代码太复杂了。说真的,阅读它并理解每一个细节需要我付出一些努力。这是非常重复的,并且有很多可能会出现破坏正确性的简单错误。对三个数字进行排序的代价太高了。

不要重新发明轮子并了解您的<algorithm>

您想要最小的数 (std::min)、最大的数 (std::max) 和另一个数:

#include <algorithm>
#include <iostream>

int main(){
    int a = 42;
    int b = 2;
    int c = -13;

    int smallest = std::min({a,b,c});
    int biggest = std::max({a,c});
    // int middle = a+b+c-smallest-biggest;      // might overflow
    int middle = a ^ b ^ c ^ smallest ^ biggest; // no overflow

    std::cout << smallest << " " << middle << " " << biggest << "\n";
}

Live Demo

指出溢出并提供非溢出解决方案的功劳归功于 PatrickRoberts。

即使,例如。作为练习,您将避免使用标准算法,您仍然应该使用函数。它们不需要很复杂。已经有一个 int max(int a,int b) 将有助于大大简化您的代码。

,

为什么有这么多变量?

int small,medium,large;
std::cin >> small >> medium >> large;

// Force "small" to be the smallest.
if (small > medium) std::swap(small,medium);
if (small > large)  std::swap(small,large);

// Now to deal with "medium" and "large"
if (medium > large) std::swap(medium,large);

我错过了什么吗?

,

你的代码不好,因为

编写大量代码会产生大量产生错误的机会。

我更喜欢在 C++ 中使用 std::sort 进行排序。

#include <iostream>
#include <algorithm>

int main(void) {
    constexpr int N = 3;
    int num[N];
    for (int i = 0; i < N; i++) {
        if (!(std::cin >> num[i])) {
            std::cerr << "read error" << std::endl;
            return 1;
        }
    }
    std::sort(num,num + N);
    for (int i = 0; i < N; i++) {
        if (i > 0) std::cout << ' ';
        std::cout << num[i];
    }
    return 0;
}
,

如果不允许您使用数组并更改变量 num1num2num3 的输入值,那么我可以建议仅使用三个 if 语句的以下解决方案

#include <iostream>
#include <functional>

int main() 
{
    int num1,num2,num3;
    auto small = std::cref( num1 ),medium = std::cref( num2 ),large = std::cref( num3 );

    std::cin >> num1 >> num2 >> num3;
    
    if ( medium.get() < small ) std::swap( medium,small );
    if ( large.get() < medium ) std::swap( large,medium );
    if ( medium.get() < small ) std::swap( medium,small );
    
    std::cout << "small = " << small
              << ",medium = " << medium
              << ",large = " << large
              << '\n';
              
    return 0;
}

如果输入例如以下值

5 3 4

那么输出将是

small = 3,medium = 4,large = 5

在某些方面与您的方法类似的另一种方法如下

#include <iostream>
#include <functional>
#include <algorithm>

int main() 
{
    int num1,num3;
    int small,large;

    std::cin >> num1 >> num2 >> num3;
    

    if ( not ( num2 < num1 ) and not ( num3 < num1 ) ) 
    {
        small = num1;
        std::tie( medium,large ) = std::minmax( num2,num3 );
    }       
    else if ( not ( num3 < num2 ) ) 
    {
        small = num2;
        std::tie( medium,large ) = std::minmax( num1,num3 );
    } 
    else 
    {
        small = num3;
        std::tie( medium,num2 );
    }

    std::cout << "small = " << small
              << ",large = " << large
              << '\n';
              
    return 0;
}

再次输入与上图相同的值序列

5 3 4 

那么输出将是

small = 3,large = 5

对于您的原始解决方案,您可以减少 if 语句条件中子表达式的数量。例如

#include <iostream>

int main() 
{
    int num1,large;

    std::cin >> num1 >> num2 >> num3;
    

    if ( not ( num2 < num1 ) and not ( num3 < num1 ) ) 
    {
        small = num1;
        if ( not ( num3 < num2 ) )
        {
            medium = num2;
            large = num3;
        }
        else
        {
            medium = num3;
            large = num2;
            
        }
    }       
    else if ( not ( num3 < num2 ) ) 
    {
        small = num2;
        if ( not ( num3 < num1 ) )
        {
            medium = num1;
            large = num3;
        }
        else
        {
            medium = num3;
            large = num1;
            
        }
    } 
    else 
    {
        small = num3;
        if ( not ( num2 < num1 ) )
        {
            medium = num1;
            large = num2;
        }
        else
        {
            medium = num2;
            large = num1;
            
        }
    }

    std::cout << "small = " << small
              << ",large = " << large
              << '\n';
              
    return 0;
}
,

对于三个数字的排序问题,这不是一个糟糕的解决方案。它相当容易遵循,它表现得相当好。并且很容易验证其正确性。

但您应该非常感到惊讶——在现实世界或学术界——如果你被要求做的下一件事不是对四个数字进行排序,或者对 n 数字进行排序.您的方法不适用于 n 的任何其他值,并且无法真正扩展。