Even and odd sorting arrays - c++

I can't get the following program to sort 'orig', 'even', and 'odd' arrays in ascending order.
The code seems fine to me, but it doesn't sort correctly at all, it will separate the array into the original even and odd lists, but the order is random and not in ascending order at all.
The output should look something like this:
Input up to 50 integers. Use a negative number to stop.
The list will be sorted into odd and even values.
Input an integer: 15
Input an integer: 8
Input an integer: 22
Input an integer: 4
Input an integer: 77
Input an integer: 19
Input an integer: 2
Input an integer: -1
Orig Even Odd
2 2 15
4 4 19
8 8 77
15 22
19
22
77
#include<iostream>
#include<iomanip>
using namespace std;
void DataIn(int Max[], int List[][50]);
void Separate(int Max[], int List[][50]);
int Lowest(int start, int N, int Vector[]);
void Sort(int Max[], int List[][50]);
void DataOut(int Max[], int List[][50]);
int main()
{
//Index: 0 = input, 1 = even, 2 = odd
int Max[3] = { 0, 0, 0 };
int List[3][50];
cout << "Input up to 50 integers. Use a negative number to stop.\n";
cout << "The list will be sorted into odd and even values.\n\n";
DataIn(Max, List);
Separate(Max, List);
Sort(Max, List);
DataOut(Max, List);
}
void DataIn(int Max[], int List[][50])
{
cout << "Input an integer: ";
cin >> List[0][Max[0]];
while (List[0][Max[0]] > 0)
{
cout << "Input an integer: ";
cin >> List[0][++Max[0]];
}
return;
}
void Separate(int Max[], int List[][50])
{
int n, type;
for (n = 0; n < Max[0]; ++n)
{
if ((List[0][n] % 2) == 0)
type = 1;
else
type = 2;
List[type][Max[type]++] = List[0][n];
}
return;
}
int Lowest(int start, int N, int Vector[])
{
int i, low = start;
for (i = start + 1; i < N; i++)
if (Vector[i] < Vector[low])
low = i;
return (low);
}
void Sort(int Max[], int List[][50])
{
int i, j, k, l;
double origSort,evenSort,oddSort;
for (i = 0; i < Max[0] - 1; ++i)
{
j = Lowest(i, Max[0], List[50]);
origSort = List[0][i];
List[0][i] = List[0][j];
List[0][j] = origSort;
k = Lowest(i, Max[1], List[50]);
evenSort = List[1][i];
List[1][i] = List[1][k];
List[1][k] = evenSort;
l = Lowest(i, Max[2], List[50]);
oddSort = List[2][i];
List[2][i] = List[2][l];
List[2][l] = oddSort;
}
}
void DataOut(int Max[], int List[][50])
{
int i;
int orig = 0, even = 1, odd = 2;
cout << "\n\n";
cout << setw(10) << "Orig" << setw(10) << "Even" << setw(10) << "Odd" << "\n\n";
for (i = 0;i < Max[0];i++)
{
if(List[0][i]>0)
cout << setw(10) << List[orig][i];
else
cout << setw(10) << " ";
if (List[1][i] > 0)
cout << setw(10) << List[even][i];
else
cout << setw(10) << " ";
if (List[2][i] > 0)
cout << setw(10) << List[odd][i] << "\n";
else
cout << "\n";
}
}

You have overcomplicated yourself too much with a two dimensional array and whatever int Max[3] is.
Things are simple: sort the original vector, then filter the odds and evens. Since you filter after you sort, the two resulting vectors will already be sorted.
Here's the C++20 solution:
int main()
{
using namespace std::ranges::views;
std::vector<int> v{15, 8, 22, 4, 77, 19, 2};
std::ranges::sort(v);
auto evens = v | filter([] (int a) { return a % 2 == 0; });
auto odds = v | filter([] (int a) { return a % 2 != 0; });
for (auto e : v)
std::cout << e << " ";
std::cout << std::endl;
for (auto e : evens)
std::cout << e << " ";
std::cout << std::endl;
for (auto e : odds)
std::cout << e << " ";
std::cout << std::endl;
}
You don't even need the variables to store the ranges. You can do the filter in the output loop if you want:
for (auto e : v | filter([] (int a) { return a % 2 == 0; }))
std::cout << e << " ";
std::cout << std::endl
And here's the non-ranges solution:
int main()
{
std::vector<int> v{15, 8, 22, 4, 77, 19, 2};
std::vector<int> evens;
std::vector<int> odds;
std::sort(v.begin(), v.end());
std::copy_if(v.begin(), v.end(), std::back_inserter(evens),
[] (int a) { return a % 2 == 0; });
std::copy_if(v.begin(), v.end(), std::back_inserter(odds),
[] (int a) { return a % 2 != 0; });
for (auto e : v)
std::cout << e << " ";
std::cout << std::endl;
for (auto e : evens)
std::cout << e << " ";
std::cout << std::endl;
for (auto e : odds)
std::cout << e << " ";
std::cout << std::endl;
}
If you for whatever reason don't want to use the standard library algorithms you must at least use the standard containers. Ditch the C arrays. And implement the solution following the same logic: sort then filter.

Related

why isn't my vector pushbacking even and odd numbers

i tried to separate even and odd numbers using vectors from a array ==>
so i made a function that returns true is number is even and false for if number is odd
then i used an if else statement where if the function returns true then it pushbacks the value in a vector and if the function returns false then it pushbacks the value in another vector , finally i printed all the elements in the vector but the output does not show any element except it shows one in the odd vector.
#include <iostream>
#include <vector>
using namespace std;
bool sort(int arr[] , int i){
if(arr[i] %2 == 0){
return true;
}
return false;
}
int main(){
int n;
cin >> n;
int *arr = new int[n];
for(int i=1 ; i<=n ; i++){
arr[i-1] = i;
}
vector <int> even , odd;
int i=0 ;
if(sort(arr , i)){
even.push_back(arr[i]);
sort(arr , i+1);
}else{
odd.push_back(arr[i]);
sort(arr,i+1);
}
cout << "the even numbers are : " << endl;
for(auto element:even){
cout << element << " ";
}
cout << endl;
cout << "the odd numbers are : " << endl;
for(auto element:odd){
cout << element << " ";
}
}
As #TonyDelroy said, you have to make for loop around call to sort(arr, i). Also first loop should go up to i <= n instead of i < n.
Your fixed working code below (see also std::partition_copy variant afterwards):
Try it online!
#include <iostream>
#include <vector>
using namespace std;
bool sort(int arr[] , int i){
if(arr[i] %2 == 0){
return true;
}
return false;
}
int main(){
int n;
cin >> n;
int *arr = new int[n];
for(int i=1 ; i<=n ; i++){
arr[i-1] = i;
}
vector <int> even , odd;
for (int i = 0; i < n; ++i)
if (sort(arr, i))
even.push_back(arr[i]);
else
odd.push_back(arr[i]);
cout << "the even numbers are : " << endl;
for(auto element:even){
cout << element << " ";
}
cout << endl;
cout << "the odd numbers are : " << endl;
for(auto element:odd){
cout << element << " ";
}
}
Input:
10
Output:
the even numbers are :
2 4 6 8 10
the odd numbers are :
1 3 5 7 9
As #chris said you can also use std::partition_copy to implement your algorithm:
Try it online!
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
int n = 0;
std::cin >> n;
std::vector<int> arr(n), odd, even;
for (int i = 1; i <= n; ++i)
arr[i - 1] = i;
std::partition_copy(arr.cbegin(), arr.cend(),
std::back_insert_iterator(odd), std::back_insert_iterator(even),
[](auto const & x){ return (x & 1) == 1; });
std::cout << "the even numbers are : " << std::endl;
for (auto element: even)
std::cout << element << " ";
std::cout << std::endl << "the odd numbers are : " << std::endl;
for (auto element: odd)
std::cout << element << " ";
}
Input:
10
Output:
the even numbers are :
2 4 6 8 10
the odd numbers are :
1 3 5 7 9
You only push one element - the first.
Your partitioning code is equivalent to
if(sort(arr , 0)){
even.push_back(arr[0]);
sort(arr , 1);
}else{
odd.push_back(arr[0]);
sort(arr,1);
}
You need to loop over all the input numbers.
You can also simplify matters with a more generally useful evenness function that doesn't depend on an array:
bool is_even(int x) { return x % 2 == 0; }
and then there is no need to store all the inputs before processing them:
int main(){
vector <int> even , odd;
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
if (is_even(x)) {
even.push_back(x);
}
else {
odd.push_back(x);
}
}
cout << "the even numbers are : " << endl;
for (auto element:even){
cout << element << " ";
}
cout << endl;
cout << "the odd numbers are : " << endl;
for (auto element:odd){
cout << element << " ";
}
}

How can I convert for loops into for-each loops?

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

Iterate though array of int by prime numbers at C++

I leave the complete code so that you can understand the context.
My problem is on line 53 (it says "HERE HERE...")...
The purpose of the code is to decompose a number(n) dividing it by prime numbers and printing at all in a chart.
Basically the problem is how to iterate through an int array by prime numbers.
I hope find help...
Please let me know any feedback
#include <iostream>
#include <math.h>
using namespace std;
int main (){
char slot;
int primo, div = 0;
int m;
//Ask to user, the size(slot) of our Array (memory[])
cout << "Escoga la memoria que mas se acomode a su necesidad y RAM: \t\n"
<< " A) 512 slots\n"
<< " B) 128 slots\n"
<< " C) 64 slots\n"
<< " > ";
cin >> slot;
if (slot == 'a' || 'A')
{
m = 512;
}
if (slot == 'b' || 'B')
{
m = 128;
}
if (slot == 'c' || 'C')
{
m = 64;
}
int memory[m];
// Storage in Array memory all prime numbers between 1 and m.
for (int i = 1; i <= m; i++)
{
primo = 0;
for (div = 2; div < i - 1 && primo == 0; div++)
{
if (i % div == 0) primo = 1;
}
if (primo == 0)
memory[i] = i;
}
//Ask to user, for give a number.
//n = The number that we gonna descompose arithmetically
cout << "Inserte un numero: ";
cin >> n;
cout << " | " << n << "\n";
<< "-------\n";
//HERE HERE HERE
//Iterate through memory [] printing the descompose of n
for ("HERE I NEED ITERATE FROM" memory[2] "UNTIL" memory[63])
{
do
{
n /= j;
cout << " " << j << " | " << n << "\n";
}while((n % j) == 0);
}
}
#include <array>
#include <iostream>
const int SIZE = 10;
int main()
{
int m = 8;
std::array<int, SIZE> arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (auto i : arr) { // How to iterate all elements of std::array
std::cout << i << ' ';
}
std::cout << '\n';
// Another way to do the same thing (print all elements)
std::copy(arr.begin(), arr.end(), std::ostream_iterator<int>(std::cout, " "));
// Getting to your actual question
if (m < arr.size()) {
for (int i = 2; i < m; ++i) {
std::cout << arr[i] << ' ';
}
std::cout << '\n';
}
}

How to transfer elements from vector to a new array?

I need to transfer elements from the total costs (int totalCosts) into a new array to be called costs[]. I tried doing this at the end of the code but when I tried to access the first element in the array, it shows ALL the total costs from the output. I only needed to access the first one.
// ******** CREATE "example.txt" IN THE FOLDER THAT HAS THE PROJECT'S .CPP FILE ********
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <list>
#include <iterator>
using namespace std;
class vehicle_capacities {
public:
int lw, vw;
};
double nearest_ten(double n)
{
return round(n / 10.0 + 0.4) * 10.0;
}
bool cmp_fn(int a, int b)
{
return a > b;
}
int main()
{
int cw;
vehicle_capacities cap;
cap.lw = 30;
cap.vw = 10;
ifstream myfile("example.txt");
if (myfile.is_open()) {
myfile >> cw;
myfile.close();
}
else {
cout << "Unable to open file" << endl;
}
cout << "Amount of cargo to be transported: " << cw;
cw = nearest_ten(cw);
cout << "(" << cw << ")" << endl;
int maxl = cw / cap.lw; // maximum no. of lorries that can be there
vector<pair<int, int>> solutions;
//vector<int> costs;
vector<int>::iterator it;
// for the inclusive range of 0 to maxl, find the corresponding no. of vans for each variant of no of lorries
for (int l = 0; l <= maxl; ++l) {
bool is_integer = (cw - l * cap.lw) % cap.vw == 0; // only if this is true, then there is an integer which satisfies for given l
if (is_integer) {
int v = (cw - l * cap.lw) / cap.vw; // no of vans
solutions.push_back(make_pair(l, v));
}
}
cout << "Number of mini-lorries: ";
for (auto& solution : solutions) {
cout << solution.first << " ";
}
cout << "\n";
cout << "Number of vans: ";
for (auto& solution : solutions) {
cout << solution.second << " ";
}
cout << "\n";
cout << "Total cost: ";
// LORRY COST = $200, VAN COST = $45
for (auto& solution : solutions) {
int totalCosts = (solution.first * 200) + (solution.second * 45);
cout << totalCosts << " ";
}
/*for (auto& solution : solutions) {
int totalcosts = (solution.first * 200) + (solution.second * 45);
costs.push_back(totalcosts);
for (it = costs.begin(); it < costs.end(); it++) {
cout << *it << " ";
}
}*/
cout << endl;
// Comparison between both vehicles, highest amount = trips needed
cout << "Trips Needed: ";
for (auto& solution : solutions) {
int a = solution.first;
int b = solution.second;
if (a > b) {
cout << a << " ";
}
else if (b > a) {
cout << b << " ";
}
else if (a == b) {
cout << a << " ";
}
}
cout << endl;
cout << "Lowest #1: ";
for (auto& solution : solutions) {
int totalCosts[] = { (solution.first * 200) + (solution.second * 45) };
int elements = sizeof(totalCosts) / sizeof(totalCosts[0]);
sort(totalCosts, totalCosts + elements, cmp_fn);
for (int i = 0; i < elements; ++i) // print the results
cout << totalCosts[i] << " ";
cout << totalCosts[0] << " ";
}
// *** FOR SORTING ELEMENTS IN ARRAY LOW TO HIGH ***
/*int array[] = { 1,10,21,55,1000,556 };
int elements = sizeof(array) / sizeof(array[0]); // Get number of elements in array
sort(array, array + elements);
for (int i = 0; i < elements; ++i) // print the results
cout << array[i] << ' ';*/
return 0;
}
Do update if you have any solutions, thank you.
(Note that you have to create "example.txt" in project file.
You need to dynamically allocate your array.
int elements = solution.size();
int *totalCosts = new int[elements];
int j= 0;
// transfer data
for (auto& solution : solutions) {
totalCosts[j++] = (solution.first * 200) + (solution.second * 45);
}
sort(totalCosts, totalCosts + elements, cmp_fn);
for (int i = 0; i < elements; ++i) // print the results
cout << totalCosts[i] << " ";
cout << totalCosts[0] << " ";
delete[] totalCosts;

Comparing unsorted elements in two vectors

I'm new to C++ and I'm trying to compare two unsorted vectors elements against each other and determining if they match or not.
for example:
1 4 9 16 9 7 4 9 11 and 11 11 7 9 16 4 1
these would be considered a match.
I've tried using firstVector == secondVector, but that does not work when they vectors are not sorted, I'm specifically trying to compared them while they are unsorted but am struggling.
int main() {
int incorrectMatches = 0;
int totalMatches = 0;
int input = 0;
vector <int> firstVector;
vector <int> secondVector;
do {
cout << "Please enter a number for first vector: ";
cin >> input;
firstVector.push_back(input);
cout << endl;
}
while (input > 0);
input = 0;
firstVector.pop_back();
do {
cout << "Please enter a number for second vector: ";
cin >> input;
secondVector.push_back(input);
cout << endl;
}
while (input > 0);
secondVector.pop_back();
for (int loop = 0; loop < firstVector.size(); loop++) {
cout << firstVector[loop] << " ";
}
cout << endl;
for (int loop = 0; loop < secondVector.size(); loop++) {
cout << secondVector[loop] << " ";
}
cout << endl;
int vectorSize = firstVector.size();
for (int i = 0; i < vectorSize; i++) {
if (firstVector[i] == secondVector[i]) {
totalMatches = totalMatches++;
}
else {
incorrectMatches = incorrectMatches++;
}
}
cout << "There were " << totalMatches << " matches." << endl;
cout << "There were " << incorrectMatches << " incorrect matches";
/*
if (firstVector == secondVector) {
cout << "Your vectors match!";
}
else{
cout << "Your vectors don't match!";
}
*/
/*
for (int i = 0; i < input; i++) {
cout << "Please enter a number (1-9): ";
myVector.push_back(input);
cout << endl;
myVector[i] = i;
cout << "Vector entry: " << myVector[i] << endl;
}
*/
system("pause");
return 0;}
As duplicates shall not matter, you could simply insert the elements of the vectors in a separate std::set, respectively, and then compare the sets using operator ==. I think the use of sets expresses the intent of your program best:
int main() {
vector<int> v1 = { 1, 4, 9, 16, 9, 7, 4, 9, 11 };
vector<int> v2 = { 11, 11, 7, 9, 16, 4, 1 };
set<int> s1;
s1.insert(v1.begin(), v1.end());
set<int> s2;
s2.insert(v2.begin(), v2.end());
bool isEqual = (s1 == s2);
cout << "v1 and v2 are " << (isEqual ? "" : "not ") << "equal." << endl;
return 0;
}