【问题标题】:How do I use a for loop to print out alternating information from arrays?如何使用 for 循环从数组中打印出交替信息?
【发布时间】:2015-09-07 18:15:14
【问题描述】:

对于这个令人困惑的标题,我真的很抱歉,但如果不向您展示代码,我不知道如何表达这个问题。所以这是我的问题。我正在尝试打印出 20 个学生信息,这些信息都包含在 3 个不同的数组中(身份证号、姓氏和年龄)。数组(和向量)是这样的:

vector<int> studentNumber (20);
int age [20] {20, 21, 22, 42, 55, 28, 20, 20, 19,19, 22, 23, 25, 26, 24, 23, 19, 22, 21, 20};
string lastName [20] {"Simmons", "Jones", "James", "Little", "Russell", "Haynes", "Marcotte", "Kemper", "Vandergore", "Hume", "Stephens", "Jensen", "Biersack", "Sykes", "Joseph", "Dunn", "Hai", "Meteos", "Aphromoo", "Faker"};

我正在使用 3 个 for 循环来打印所有这些信息,并且它们都可以正常工作。它们是这样的:

void getAllStudentInfo() {
    for (vector<int>::size_type i = 0; i <= 20; i++) {
    cout << "Student's ID number is: " << 400 + i << endl;
    }
    for (int i = 0; i < 20; i++) {
        cout << "Student's last name is: " << lastName[i] <<endl;
    }
    for (int i = 0; i < 20; i++) {
        cout << age[i] << endl;
    }
    return;
}

所以他们现在所做的是将信息打印为 20 个身份证号码、20 个姓氏和 20 个年龄。我希望他们做的是打印每个数组中的前 3 个元素,然后是后三个元素,然后是第三个元素,依此类推。所以它看起来像,(身份证号,姓氏,年龄)重复二十次,而不是(身份证号x20,姓氏x20,年龄x20)。我将如何重构它以使其看起来像我想要的那样?

【问题讨论】:

  • std::cout同一循环中的不同信息。
  • 并将&lt;= 20更改为&lt; 20
  • 他们都需要一个数组来做到这一点吗?当我结合姓氏和年龄时效果很好,但我如何整合 ID 号?
  • 想通了。谢谢大家。
  • (小点:“refactoring”意思是改变实现而不改变行为。)

标签: c++ arrays for-loop vector


【解决方案1】:

您需要将您的 for 循环组合成一个循环。 首先,您对数据结构的选择是不寻常的。为什么要混合向量和数组?对所有三个都使用向量可能会更好。然后可以在运行时确定学生的数量,加上好的调试器将执行边界检查。您还应该避免在代码中硬编码幻数,例如 20。如果数字需要更改,则更难更新代码。此外,我不确定studentNumber 向量的意义是什么,因为您从未在其中存储任何数据。你只是想要一个柜台吗? (使用 int)

使用您的数据结构的代码如下:

for (size_t i = 0; i < numStudents; i++)
{
    cout << "Student's ID number is: " << 400 + i << "\n";
    cout << "Student's last name is: " << lastName[i] << "\n";
    cout << age[i] << "\n";
}

根据您希望如何设计程序,将这三条信息组合到一个对象中可能会更好。这是一个简单的方法:

struct Student
{
    Student(int id, int age, const string& name)
        : id(id), age(age), name(name)
    {}

    int id;
    int age;
    string name;
};

您可以在以后了解它们时添加诸如 getter 和 setter 之类的细节。

现在像这样填充学生的数据结构:

vector<Student> allStudents;

// optional - if you know the number of students in advance, you can give a hint to the vector to increase its performance. the number does not need to be exact and calling reserve does not increase the number of elements in the vector right away
allStudents.reserve(20);

// add student data, possibly from a file?
allStudents.push_back(Student(400, 15, "Billy"));
allStudents.push_back(Student(401, 16, "Sally"));
// alternative slightly more efficient syntax for C++11
allStudents.emplace_back(402, 15, "Jill");

现在只有一个数据结构供您迭代。你可以这样做:

for (size_t i = 0; i < allStudents.size(); i++)
{
    cout << "Student's ID number is: " << allStudents[i].id << "\n";
    cout << "Student's last name is: " << allStudents[i].name << "\n";
    cout << allStudents[i].age << "\n";
}

在 C++11 中,您可以使用更方便的语法:

// remove the const keyword if you want to be able to write to student objects in the vector
for (const auto& student : allStudents)
{
    cout << "Student's ID number is: " << student.id << "\n";
    cout << "Student's last name is: " << student.name << "\n";
    cout << student.age << "\n";
}

请注意您的数据是如何保存在一个合乎逻辑的位置的,如果您不想硬编码大量学生,则无需硬编码,一个好的调试器现在将执行更多的边界检查。

现场示例: http://ideone.com/gsvbYa

【讨论】:

    【解决方案2】:

    如果您不需要或不想使用直接原始数组,您可以包含与类结构相关的所有这些信息,您可以在该类对象上实现打印函数或添加重载 std::cout

    struct StudentInformation {
        unsigned m_id;
        unsigned m_age;
        std::string m_lastName;
    
        StudentInformation( unsigned uId, unsigned uAge, const std::string& strLastName ) :
        m_id( uId ), m_age( uAge ), m_lastName( strLastName ) {
    }; 
    
    class StudentInformationList {
        friend std::ostream& operator<<( std::ostream& out, const StudentInformation* const studentInformation ); 
    private:
        std::vector<StudentInformation> m_vStudents;
    
    public:
        StudentInformation();
        explicit StudentInformation( StudentInformation& studentInformation );
    
        void addStudentToList( const StudentInformation& studentInformation );
        std::vector<StudentInformation>& getStudentList() const;
        StudentInformation& getStudent( const unsigned id ) const;
        StudentInformation& getStudent( const std::string& strName ) const;
    
    };
    

    这将是类声明,您必须从这里适当地实现函数。

    【讨论】:

    • 看了这个之后,有几种不同的方法可以使用 std::cout 对象的流运算符。您可以让列表使用流运算符并循环遍历列表中的所有对象,也可以将此运算符添加到 StudentInformation 结构中,以便为该对象的每个实例打印数据()。
    【解决方案3】:
    • 您可以简单地在单个循环中打印 Id、name 和 age。

      void getAllStudentInfo() 
      {
      
        vector<int> studentNumber(20);
        int age [20] {20, 21, 22, 42, 55, 28, 20, 20, 19,19, 22, 23, 25, 26, 24, 23, 19, 22, 21, 20};
        string lastName [20] {"Simmons", "Jones", "James", "Little", "Russell", "Haynes", "Marcotte", "Kemper", "Vandergore", "Hume", "Stephens", "Jensen", "Biersack", "Sykes", "Joseph", "Dunn", "Hai", "Meteos", "Aphromoo", "Faker"};
        int i;
        for (vector<int>::size_type i = 0; i < 20; i++)
        {
          cout << "Student's ID number is: " << 400 + i << endl;
          cout << "Student's last name is: " << lastName[i] <<endl;
          cout << age[i] << endl;
        }
        return;
        }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-11
      • 2013-02-20
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      相关资源
      最近更新 更多