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

时间:2014-10-13 05:12:15

标签: c++ arrays sorting

首先,我会公开承认这是一项家庭作业。话虽这么说,我的代码非常接近,并希望在正确的方向上轻推。

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

示例输入:

洁具亨利87.2 丹特斯爱德蒙91.4 Earhart Amelia 92.6

我的代码接受用户输入,根据姓氏,然后是名字交换它们,并输出学生和GPA列表。测试我的代码的在线程序输入六(6)名学生数据。它使用Swap对它们进行了正确的排序,但是第5个学生从条目5-49(满分为50个)重复,最后输出了学生6.我已经搜索了论坛,但没有找到适用的先前帖子。 / p>

我尝试过使用' 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;
}

2 个答案:

答案 0 :(得分:2)

#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;
}

/ 评论:我相信这个作业来自myprogramminglab。你需要解决的唯一问题是从50变为5,myprogramminglab只输入5个条目而不是50条,因为它说 /

答案 1 :(得分:0)

程序的输入数量仅保证为<= 50,实际上在测试数据中,只有6个条目,在样本输入中只有3个。

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

从您的样本输入中,所有数据都在一行输入。这意味着我们可以使用this answer中描述的方法来处理输入。

您的输入循环现在如下所示:

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 see here for why 使用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

你正在进行冒泡排序(我猜这是你的意图),但只做一次通过。 我可以在这里回答,但作为一个单独的问题,你应该在另一个问题中提出这个问题。

相关问题