使用Swap函数对类对象数组进行排序后出现重复条目-C++

Duplicate entries after using Swap function to sort an array of class objects - C++

本文关键字:-C++ 排序 函数 Swap 对象 数组 使用      更新时间:2023-10-16

首先,我要公开承认这是一项家庭作业。话虽如此,我的代码非常接近,希望能朝着正确的方向前进。

提示:编写一个完整的程序,从标准输入中读取学生数据,按姓氏/名字排序,并将结果打印到标准输出中。学生数据由姓氏、名字和平均绩点(浮点值)组成。你应该假设不超过50名学生。

样本输入:

Ware Henry 87.2唐兹埃德蒙德91.4Earhart Amelia 92.6

我的代码接受用户输入,根据姓氏和名字进行交换,并输出学生列表和GPA。测试我的代码的在线程序输入了六(6)名学生的数据。它使用Swap对它们进行正确排序,但第五个学生从条目5-49(共50个)开始重复,最后输出学生6。我搜索过论坛,但没有找到以前的帖子。

我曾尝试在输出循环中使用"while"语句,但我对布尔值的理解仍然有点薄弱。所尝试的while语句列在我的代码的顶部。如有任何协助,我们将不胜感激。

while((list[i].lastName != list[i + 1].lastName) && (list[i].firstName != list[i + 1].firstName))
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class student
{
public:
    string firstName;
    string lastName;
    float gpa;
    student() {};
    student(string last, string first, double grade)
    {
        firstName = first;
        lastName = last;
        gpa = grade;
    };
};
int main()
{
    string first;
    string last;
    float grade;
    student list[50];

    for(int i = 0; i < 50; i++)
    {
        cin >> last;
        cin >> first;
        cin >> grade;
        list[i].lastName = last;
        list[i].firstName = first;
        list[i].gpa = grade;
    }
    for ( int i = 0; i < 50 - 1; i++)
        {
            if (list[i].lastName > list[i + 1].lastName)
            {
                swap (list[i], list[i+1]);
            }
        }
        for ( int i = 0; i < 50 - 1; i++)
        {
            if (list[i].firstName > list[i + 1].firstName)
            {
            swap (list[i], list[i+1]);
            }
        }

        for(int i = 0; i < 50 - 1; i++)
        {
            cout << list[i].lastName << " " << list[i].firstName << " " << list[i].gpa << endl;
        }
    return 0;
}
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class student
{
public:
    string firstName;
    string lastName;
    float gpa;
    student() {};
    student(string last, string first, double grade)
    {
        firstName = first;
        lastName = last;
        gpa = grade;
    };
};
int main()
{
    string first;
    string last;
    float grade;
    student list[5];

    for(int i = 0; i < 5; i++) //use 5 instead of 50 because myprogramminglab only input 5 entries, not 50, it lies to you
    {
        cin >> last;
        cin >> first;
        cin >> grade;
        list[i].lastName = last;
        list[i].firstName = first;
        list[i].gpa = grade;
    }
    for ( int i = 0; i < 4; i++)
        {
            if (list[i].lastName > list[i + 1].lastName)
            {
                swap (list[i], list[i+1]);
            }
        }
        for ( int i = 0; i < 4; i++)
        {
            if (list[i].firstName > list[i + 1].firstName)
            {
            swap (list[i], list[i+1]);
            }
        }

        for(int i = 0; i < 5; i++)
        {
            cout << list[i].lastName << " " << list[i].firstName << " " << list[i].gpa << endl;
        }
    return 0;
}

/评论:我相信这个作业来自我的编程实验室。您唯一需要修复的是从50更改为5,myprogramminglab只输入5个条目,而不是50,因为它说/

程序的输入数量只能保证为<= 50,事实上,在测试数据中只有6个条目,而在示例输入中只有3个。

您的问题在于,当前每次运行程序都需要50个条目,而当cin >> variable失败时,则不会写入任何数据。

根据您的示例输入,所有数据都在一行中输入。这意味着我们可以使用这个答案中描述的方法来处理输入。

您的输入循环现在看起来是这样的:

int count = 0;
std::string line;
std::getline(cin, line);
std::istringstream iss(line);
while ((iss >> last) && (iss >> first) && (iss >> grade))
{
    list[count].lastName = last;
    list[count].firstName = first;
    list[count].gpa = grade;
    cout <<"student: "<< last << " " << " " << first << " " << grade << endl;
    count++;
}

我们现在一次性读取整行内容,然后使用流运算符>>进行读取。
从功能上讲,这与您的原始代码非常相似,但与cin不同的是,流有一个结尾
iss >> variable到达数据末尾时,它将返回false,这将使我们脱离循环。此时,count变量的值将等于输入的学生数据集的数量。

我们现在可以在其余的循环中使用count(而不是50)。

完整代码:

#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
using namespace std;
class student
{
public:
    string firstName;
    string lastName;
    float gpa;
    student() {};
    student(string last, string first, double grade)
    {
        firstName = first;
        lastName = last;
        gpa = grade;
    };
};
int main()
{
    string first;
    string last;
    float grade;
    student list[50];
    int count = 0;
    std::string line;
    std::getline(cin, line);
    std::istringstream iss(line);
    cout<<"input data: n";
    while ((iss >> last) && (iss >> first) && (iss >> grade))
    {
        list[count].lastName = last;
        list[count].firstName = first;
        list[count].gpa = grade;
        cout <<"student: "<< last << " " << " " << first << " " << grade << endl;
        count++;
    }
    for ( int i = 0; i < count-1; i++)
        {
            if (list[i].lastName > list[i + 1].lastName)
            {
                swap (list[i], list[i+1]);
            }
        }
        for ( int i = 0; i < count-1; i++)
        {
            if (list[i].firstName > list[i + 1].firstName)
            {
            swap (list[i], list[i+1]);
            }
        }

        for(int i = 0; i < count; i++)
        {
            cout << list[i].lastName << " " << list[i].firstName << " " << list[i].gpa << endl;
        }
    return 0;
}

我在ideone上为您准备了一个运行版本:http://ideone.com/Y9jOkt然而,我在这个版本中做了一些进一步的增强:已删除using namespace std请参阅此处了解原因使用std::vector而不是裸阵列的控制器将适应输入的数量而不是固定大小。创建了一个locat current_student对象来读取数据,保持意图清晰,并且与std::vector配合良好。也可以使用裸阵列完成。

我还想指出,你的这类人是不对的
此输入:

f f 9 e e 8 d d 7 c c 6 b b 5 a a 4

应提供以下输出:

a a 4
b b 5
c c 6
d d 7
e e 8
f f 9

但结果是这样的:

d d 7
c c 6
b b 5
a a 4
e e 8
f f 9

你在做一个泡泡式的动作(我想这是你的本意),但只做了一次传球。我可以在这里回答,但作为一个单独的问题,你可能应该在另一个问题中问这个问题。