My task is to convert my for
loops into for-each
loops.
The task begins with creating a two dimensional array 6x30. This represents 6 classes of 30 students each. Each position in the array contains a random number between 55 and 100 which represents a student score.
Next I display that array to the console.
Next I calculate the average score of each class.
Next I find the highest average among the 6 classes and display that to the screen.
I am using Xcode on MacBook Pro.
Question: How can I properly convert my for
loops into for-each
loops?
My code is below:
#include <iostream>
#include <iomanip>
using namespace std;
const int NUM_CLASSES = 6, NUM_STUDENTS_PER_CLASS = 30;
void bubbleSort(int arr[], int n){
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] < arr[j + 1])
swap(arr[j], arr[j + 1]);
}
}
}
void classGradeGeneration() {
int arrayOne[NUM_CLASSES][NUM_STUDENTS_PER_CLASS], classAverage[NUM_CLASSES];
//Generating random average student scores until array filled
for (int classNumber = 0; classNumber < NUM_CLASSES; classNumber++) {
for (int column = 0; column < NUM_STUDENTS_PER_CLASS; column++) {
arrayOne[classNumber][column] = rand() % 46 + 55;
}
}
//Displaying array of student scores
for (int classNumber = 0; classNumber < NUM_CLASSES; classNumber++) {
cout << "Class " << classNumber + 1 << ": ";
for (int column = 0; column < NUM_STUDENTS_PER_CLASS; column++) {
cout << setw(3) << arrayOne[classNumber][column] << " ";
classAverage[classNumber] += arrayOne[classNumber][column];
}
cout << endl;
}
cout << endl;
int averageScore, averageOfClasses[NUM_CLASSES];
//Displaying average class scores
for (int temp = 0; temp < NUM_CLASSES; temp++) {
averageScore = classAverage[temp] / NUM_STUDENTS_PER_CLASS;
cout << "Class " << temp + 1 <<" Average score: " << averageScore << endl;
averageOfClasses[temp] = averageScore;
}
cout << endl;
bubbleSort(averageOfClasses, NUM_CLASSES); // Sorting average scores highest to lowest
cout << endl;
cout << "The highest average score is: " << averageOfClasses[0];
cout << endl;
}
int main () {
srand(time(NULL));
classGradeGeneration();
cout << endl << endl;
}
Below is a sample output:
You may use range-based for with std::array since C++11
constexpr int NUM_CLASSES = 6, NUM_STUDENTS_PER_CLASS = 30;
std::array<std::array<int, NUM_STUDENTS_PER_CLASS>, NUM_CLASSES> arr;
for (/*const*/ auto& ln : arr) {
std::cout << "LINE" << std::endl;
for (/*const*/ auto& elem : ln) {
std::cout << "elem" << std::endl;
}
}
or for_each if you want
std::for_each(arr.begin(), arr.end(), [](/*const*/ auto& line) {
std::cout << "LINE" << std::endl;
std::for_each(line.begin(), line.end(), [](/*const*/ auto& elem) {
std::cout << "elem" << std::endl;
});
});
But I prefer range-based for in this case.
If you use c-style array then for_each arguments will be pointers, not iterators.
int arr[NUM_CLASSES][NUM_STUDENTS_PER_CLASS], classAverage[NUM_CLASSES];
std::for_each(std::begin(arr), std::end(arr), [](/*const*/ auto& line) {
std::cout << "LINE" << std::endl;
std::for_each(std::begin(line), std::end(line), [](/*const*/ auto& elem) {
std::cout << "elem" << std::endl;
});
});
So your code may look like this
constexpr int NUM_CLASSES = 6, NUM_STUDENTS_PER_CLASS = 30;
std::array<std::array<int, NUM_STUDENTS_PER_CLASS>, NUM_CLASSES> arr;
// set random values
for (auto& ln : arr) {
for (auto& elem : ln) {
elem = std::rand() % 100;
}
}
// calculate
float avgScore = 0.0F;
for (const auto& ln : arr) {
const auto avgGroupScore = std::accumulate(std::begin(ln), std::end(ln), 0.0F) / (std::end(ln) - std::begin(ln));
avgScore = std::max(avgScore, avgGroupScore);
std::cout << "avg group score=" << avgGroupScore << "; current avgScore=" << avgScore << std::endl;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.