简体   繁体   English

C ++循环-查找最小值和第二最小值

[英]C++ Loop - Finding smallest and second smallest value

I'm very very new to C++. 我对C ++非常陌生。 Here I'm trying to write a program without any extra library. 在这里,我试图编写一个没有任何额外库的程序。 Using loops to find both the smallest value and the second smallest value from the user's inputs ( 0 is excluded and exits the program ). 使用循环从用户输入中查找最小值和第二最小值( 排除0并退出程序 )。

Here is what I tried to do. 这是我尝试做的。

#include <iostream>
using namespace std;

int main()
{
    int value=0;
    int SmallestNumber=0;
    int SmallestNumber2=0;

    cout << "Enter number to find the smallest and second smallest(or 0 to exit): ";
    cin >> value;

    while (value != 0) {

        if (value< SmallestNumber && value != 0 )
        {
            SmallestNumber = value;
        }

        else if (value<SmallestNumber && SmallestNumber2 >SmallestNumber && value != 0)
        {
            SmallestNumber2 = value;
        }

        cout << "Enter number to find the smallest and second smallest(or 0 to quit): ";
        cin >> value;

    }

    cout << "Smallest number is: " << SmallestNumber << '\n' << endl;
    cout << "Second Smallest number is: " << SmallestNumber2 << '\n' << endl;

    return 0;
}

However, this program is not functioning properly. 但是,该程序无法正常运行。 The smallest number finder works only if I input a negative value **, and the second smallest number value always outputs **0 . 最小的数字查找器仅在我输入负值**时起作用,而第二个最小的数字值始终输出** 0

Since I'm very new to C++, I tried many other solutions, but this is what I can really think of. 由于我是C ++的新手,因此尝试了许多其他解决方案,但这是我真正想到的。

Can somebody please tell me what is wrong with the program, and how I can correct it? 有人可以告诉我程序有什么问题吗,我该如何纠正?

A million thanks! 一百万谢谢! Please help me :'( 请帮我 :'(


Thanks for answering my question! 谢谢回答我的问题! I changed the initialization into this. 我将初始化更改为此。

int value;
int SmallestNumber=0;
int SmallestNumber2=0;

but how do I initialize the smallest and the second smallest values..? 但是如何初始化最小和第二个最小的值呢?

This is what I wanted my program to do 这就是我想要我的程序要做的

displaying the smallest and second smallest
    50
    1
    61
    93 
    -35
    38
    0

    -35 smallest
    1 second smallest

You start with a smallest value set to 0, so you will always get values only smaller than 0, that's why you have std::numeric_limits<int>::max() . 您将从设置为0的最小值开始,所以您总是会得到小于0的值,这就是为什么拥有std::numeric_limits<int>::max()

Then for your second smallest, you are never checking against the current second smallest value, you are just checking against the biggest, which you now is going to work. 然后,对于第二个最小值,您永远不会检查当前的第二个最小值,而只是检查最大的值,您现在就可以使用它。 So change this: 所以改变这个:

if (value>SmallestNumber2 && value != 0)

You should probably check value != 0 outside the main if statements as well. 您可能还应该在主if语句之外检查value != 0 And as @Caleb reminded me, what happens to the previous largest value if it gets replaced? 正如@Caleb提醒我的那样,如果以前的最大值被替换,将会发生什么?

You have no position at which the former smallest value becomes the second smallest value, which can't work. 您没有位置,前一个最小值变为第二个最小值,这是行不通的。

Consider this code: 考虑以下代码:

int value;
int smallest = std::numeric_limits<int>::max()-1;
int second_smallest = std::numeric_limits<int>::max();

while(true)
{
    cin >> value;

    if(value == 0) break;
    if(value >= second_smallest) continue;
    if(value == smallest) continue; // assuming that a double value does not change anything

    if(value > smallest) // is between them
    {
        second_smallest = value;
        continue;
    }

    //now the case left is that the new value is the smallest
    second_smallest = smallest;
    smallest = value;
}

Basic idea: first of all, rule out things and from then on, assume that they do not hold. 基本思想:首先,排除事物,然后假定它们不成立。 We begin with the break case (I prefer a while(true) in such cases to have manual control over breaking it inside). 我们从中断情况开始while(true)在这种情况下,我更喜欢使用while(true)来手动控制内部中断)。 Then we rule out the case in which nothing happens. 然后我们排除了什么都没有发生的情况。 The two cases left are that we are between the old values and that we are below both, and we handle them accordingly. 剩下的两种情况是,我们在旧值之间,并且都在旧值之下,并据此进行处理。

In your code, your ifs get to bloated. 在您的代码中,您的if变得肿。 Makes it hard to keep track of what is done and what is to be done. 使得难以跟踪已完成和将要执行的操作。

One example of this is that you have several times && value != 0 in your code despite this always being true due to the condition of your while. 这样的一个示例是您的代码中有几次&& value != 0 ,尽管由于您的while情况而总是如此。

In general, you should really learn how to use a debugger, or at least how to use helpful messages for debugging. 通常,您应该真正学习如何使用调试器,或者至少如何使用有用的消息进行调试。 Your mistake of setting your variables to zero at the start would have been easy to detect. 您一开始就将变量设置为零的错误很容易发现。

Other minor things: You should decide for a style and stick to it. 其他小事:您应该决定一种风格并坚持下去。 It is quite unusual to name variables with a major first letter. 用主要的第一个字母命名变量是非常不寻常的。 Camel case is fine though, smallestNumber would have been fine. 骆驼的情况很好,但是smallestNumber会很好。 Second, try to avoid using namespace std; 其次,尽量避免using namespace std; . This can lead to collissions. 这可能导致冲突。 Rather use single members of std, like using std::cout; 而是使用std的单个成员,就像using std::cout;一样using std::cout; . It is not that problematic in a source file (very problematic in a header) but I recommend to do it consistently to keep a good routine. 它在源文件中不是有问题的(在标头中不是有问题的),但我建议始终执行以保持良好的例程。

A thing left to do in the code would be to later catch if the variables are still at std::numeric_limits<int>::max() and that minus one, signalling that there was no user input, and printing a fitting message instead of those values. 代码中剩下要做的一件事是稍后捕获变量是否仍位于std::numeric_limits<int>::max()并且减一,表示没有用户输入,并打印一条适合的消息这些值。

Note that as you read in an integer, negative values are legal, which might not be what you want, given that you use zero to break. 请注意,当您读整数时,负值是合法的,如果您使用零来中断,则负值可能不是您想要的。 You might want to add a case 您可能要添加一个案例

if(value < 0)
{
    cout << "Value was ignored due to being negative" << endl;
}

This is relatively simpel by using aa few different concepts, namely , and last 通过使用一些不同的概念(即和last ,这相对

First off, the input part can be simplified to: 首先,输入部分可以简化为:

std::vector<int> numbers;

std::cout << "Enter multiple numbers, separated by spaces: ";
std::getline(std::cin, line);
std::istringstream stream(line);
while (stream >> number) {
    numbers.push_back(number);
}

Now, since you would like the 2 smallest numbers, my suggested method would be to simply sort the vector at this point: 现在,由于您想要2个最小的数字,因此我建议的方法是在此时简单地对向量进行排序:

std::sort(numbers.begin(), numbers.end());

Now the list of numbers are sorted in ascending order and it is matter of printing the 2 first values. 现在,数字列表按升序排序,这是打印两个第一个值的问题。 I leave that as an exercise to you. 我把它留给您练习。

Also, if you want to keep the same concept and do the algorithm "yourself" there is few things to change. 同样,如果您想保持相同的概念并自行执行算法,则几乎没有什么可更改的。

First the initial value of SmallestNumber and SmallestNumber2 need to be as high as possible otherwise the numbers saved can only be the one lower than your initial value. 首先,SmallestNumber和SmallestNumber2的初始值必须尽可能高,否则保存的数字只能比初始值低一个。 Therefore you can use INT_MAX. 因此,您可以使用INT_MAX。

Second, the second smallest number, need to be set in 2 cases : 第二,第二个最小的数字,在两种情况下需要设置:

  • when a new value is entered that is the second smallest 当输入第二个最小值的新值时
  • when a new smallest value is set, the old smallest value become the new second smallest. 设置新的最小值时,旧的最小值变为新的第二最小值。

Third there are a lot of unnecessary code here. 第三,这里有很多不必要的代码。 You check too many time if value is not null which you know from the while condition. 如果您从while条件知道值不为null,则检查了太多时间。 And you have code duplication with the cout/cin statement. 而且您在cout / cin语句中有代码重复。 Which is prone to mistakes. 容易出错。

Here is a version of what it could look like : 这是它的外观版本:

    int value= INT_MAX;
    int SmallestNumber=INT_MAX;
    int SmallestNumber2=INT_MAX;


    while (value != 0) {
        if(value > SmallestNumber && value < SmallestNumber2)
        {
            SmallestNumber2 = value;
        }
        else if (value< SmallestNumber)
        {
            SmallestNumber2 = SmallestNumber;
            SmallestNumber = value;
        }
        cout << "Enter number to find the smallest and second smallest(or 0 to quit): ";
        cin >> value;
    }

    cout << "Smallest number is: " << SmallestNumber << '\n' << endl;
    cout << "Second Smallest number is: " << SmallestNumber2 << '\n' << endl;

    return 0;

ps : the version of @darune is a nicer solution. ps:@darune的版本是更好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM