Sorting an array (c++) - c++

I'm studying C++ and I had the task to create array[n][m], to fill it with integer numbers, then
"Characteristic of matrix rows is called the sum of its positive even elements. You need to sort the rows of the matrix in accordance with the growth of characteristics."
It's my code
#include "stdafx.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
srand((unsigned)time(NULL));
int n, m;
cout << "n = ";
cin >> n;
cout << "m = ";
cin >> m;
int ** mas = new int * [n];
for (int i = 0; i < n; ++i)
{
mas[i] = new int[m];
}
cout << "Array:\n";
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
mas[i][j] = rand()%41-20;
cout << mas[i][j] << "\t";
}
cout << "\n";
}
double * characteristic = new double[n];
for (int i = 0; i < n; ++i)
{
characteristic[i] = 0;
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if((j%2 == 0) && (mas[i][j] >= 0))
{
characteristic[i] += mas[i][j];
}
}
}
cout << "Characteristics:\n";
for (int i = 0; i < n; ++i)
{
cout << characteristic[i] << " ";
}
cout << "\n";
for (int i = 0; i < n - 1; ++i)
{
int min = i;
for (int j = i + 1; j < n; ++j)
{
if (characteristic[min] <= characteristic[j]) continue;
min = j;
}
if (min != i)
{
double temp = characteristic[i];
characteristic[i] = characteristic[min];
characteristic[min] = temp;
for (int k = 0; k < m; ++k)
{
int temp1 = mas[i][k];
mas[i][k] = mas[min][k];
mas[min][k] = temp1;
}
}
}
cout << "\nSorted characteristics:\n";
for (int i = 0; i < n; ++i)
{
cout << characteristic[i] << " ";
}
cout << "\n";
cout << "Sorted array:\n";
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cout << mas[i][j] << "\t";
}
cout << "\n";
}
for (int i = 0; i < n; ++i)
{
delete [] mas[i];
}
delete [] mas;
delete [] characteristic;
system("PAUSE");
return 0;
}
I created another one array for characteristics and sorted it and the first array at the same time, but it seems I used too difficult way to accomplish a given task. Maybe are there other ways?

Did you want to sort the matrix too, using the same ordering as the 'characteristic's?
Let's say you had C++ style code to calculate the characteristics:
std::vector<double> characteristic(n, 0.0);
std::transform(begin(mas), end(mas), begin(characteristic), sum_);
You could then sort them:
std::sort(begin(characteristic), end(characteristic));
Or you could, indeed sort the matrix immediately:
std::sort(begin(mas), end(mas), [&sum_](int_vec const& a, int_vec const& b)
{ return sum_(a)<sum_(b); });
Edit Fixed all versions to use the correct "characteristic sum" (kept the name though), thanks #Adam
Here's a full program that demonstrates this: See it Live on Coliru
#include <random>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
typedef std::vector<int> int_vec;
srand((unsigned)time(NULL));
int n, m;
cout << "n = ";
cin >> n;
cout << "m = ";
cin >> m;
std::vector<int_vec> mas(n, int_vec(m));
for (auto& v : mas)
std::for_each(begin(v), end(v), [](int& i) { i = rand()%41-20; });
cout << "Array:\n";
for (auto const& v : mas)
{
std::copy(begin(v), end(v), ostream_iterator<int>(cout, "\t"));
cout << "\n";
}
auto sum_ = [m](int_vec const& v) {
double vchar = 0;
for (auto j = 0; j < m; j+=2)
if(v[j] >= 0) vchar += v[j];
return vchar;
};
std::vector<double> characteristic(n, 0.0);
std::transform(begin(mas), end(mas), begin(characteristic), sum_);
cout << "Characteristics:\n";
std::copy(begin(characteristic), end(characteristic), ostream_iterator<double>(cout, " "));
cout << "\n";
std::sort(begin(characteristic), end(characteristic));
cout << "\nSorted characteristics:\n";
std::copy(begin(characteristic), end(characteristic), ostream_iterator<double>(cout, " "));
cout << "\n";
std::sort(begin(mas), end(mas), [&sum_](int_vec const& a, int_vec const& b) { return sum_(a)<sum_(b); });
cout << "Sorted Array:\n";
for (auto const& v : mas)
{
std::copy(begin(v), end(v), ostream_iterator<int>(cout, "\t"));
cout << "\n";
}
}
Sample output:
n = m = Array:
11 15 19 18
-20 -16 2 -11
8 2 19 8
Characteristics:
30 2 27
Sorted characteristics:
2 27 30
Sorted Array:
-20 -16 2 -11
8 2 19 8
11 15 19 18

#sehe gives you great advice, but I suspect a lot of that stuff won't make sense until you know more C++.
Here's a simple improvement to eliminate a slow loop:
When doing your row swaps swap the row pointers instead of copying every value that they point to. Replace this:
for (int k = 0; k < m; ++k)
{
int temp1 = mas[i][k];
mas[i][k] = mas[min][k];
mas[min][k] = temp1;
}
With:
int* temp1 = mas[i];
mas[i] = mas[min];
mas[min] = temp1;
If you can figure out how to use a built-in sort algorithm that would be another improvement on top of this, but even this small change will gain you a lot.

Since the sizes n,m are known in compile time, you can use the qsort function from the C library.
#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
Where is compar is a function you write, which should treat both its arguments as pointers to a row of the matrix. Then it can calculate the characteristic of both rows, and return -1, 0 or 1 depending on which row's characteristic is greater.

Related

How to define a multidimensional array in C++ with 'n' rows and 'm' columns and iterate values using For Loop?

I want a program that asks the number of rows and columns of the multidimensional array and then using For loop iterate values in the array.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, m, x;
int a[n][m];
cin>>n>>m;
for(int i; i<n ; i++)
{
for(int j; j<m ; j++)
{
cout<<"Enter the values";
cin>>x;
a[i][j] = x;
}
}
return 0;
}
here it gets error:
main.cpp|6|warning: 'm' is used uninitialized in this function [-Wuninitialized]|
main.cpp|6|warning: 'n' is used uninitialized in this function [-Wuninitialized]|
You can't declare the array unknown size. You must do it dynamically.
#include <iostream>
using namespace std;
int main()
{
int n = 0, m = 0;
//. Get the matrix's size
while (true)
{
cout << "Input the row count: "; cin >> n;
cout << "Input the column count: "; cin >> m;
if (n < 1 || m < 1)
{
cout << "Invalid values. Please retry." << endl;
continue;
}
break;
}
//. Allocate multi-dimensional array dynamically.
int ** mat = new int *[n];
for (int i = 0; i < n; i++)
{
mat[i] = new int[m];
}
//. Receive the elements.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cout << "Input the element of (" << i + 1 << "," << j + 1 << "): ";
cin >> mat[i][j];
}
}
//. Print matrix.
cout << endl << "Your matrix:" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cout << mat[i][j] << "\t";
}
cout << std::endl;
}
//. Free memories.
for (int i = 0; i < n; i++)
{
delete[] mat[i];
}
delete[] mat;
return 0;
}
If you like to use stl, it can be simple.
#include <iostream>
#include <vector>
using namespace std;
using ROW = vector<int>;
using MATRIX = vector<ROW>;
int main()
{
int n = 0, m = 0;
MATRIX mat;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
ROW row;
row.resize(m);
for (int j = 0; j < m; j++)
{
cin >> row[j];
}
mat.push_back(row);
}
for (auto & row : mat)
{
for (auto & iter : row)
{
cout << iter << "\t";
}
cout << endl;
}
return 0;
}
Some comments.
Please never use #include<bits/stdc++.h>. This is a none C++ compliant compiler extension
Please do not use using namespace std;. Always use fully qualified names.
For the above to statements you will find thousands of entries here on SO
In C++ you cannot use VLAs, Variable Length Array, like int a[n][m];. This is not part of the C++ language
You should not use C-Style arrays at all. Use std::array or, for your case std::vector.
Use meaningful variable names
Write comments
Always initialize all variables, before using them!!!
And, last but not least. You will not learn C++ on this nonesens "competition - programming" sites.
And one of many millions possible C++ solutions (advanced) could look like that:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
// Read the dimension of the 3d data
if (unsigned int numberOfRows{}, numberOfCoulmns{}; (std::cin >> numberOfRows >> numberOfCoulmns) and (numberOfRows > 0u) and (numberOfCoulmns > 0u)) {
// Define a vector with the requested size
std::vector<std::vector<int>> data(numberOfRows, std::vector<int>(numberOfCoulmns, 0));
// Read all data
std::for_each(data.begin(), data.end(), [&](std::vector<int>& col) mutable
{ auto it = col.begin(); std::copy_n(std::istream_iterator<int>(std::cin), numberOfCoulmns, it++); });
// Show debug output
std::for_each(data.begin(), data.end(), [](std::vector<int>& col)
{std::copy(col.begin(), col.end(), std::ostream_iterator<int>(std::cout, "\t")); std::cout << '\n'; });
}
else std::cerr << "\nError: Invalid input given\n\n";
return 0;
}

Code should determine which value in an array occurs most often, but causes an error when run

This code should determine which value in the array occurs most often, but when I try to run it, it causes an error:
#include <iostream>
using namespace std;
int f(int ptr[], int size) {
int s = 0;
int* ptr2 = new int[size];
for (int y = 0; y <= size - 1; y++) {
ptr2[y] = 0;
}
for (int o = 0; o <= size; o++) {
for (int os = 0; os < size; o++) {
if (ptr[o] == ptr[os]) ptr2[o]++;
}
}
int m;
for (int l = 0; l < size - 1; l++) {
m = ptr[0];
if (m < ptr2[l + 1]) {
s = l + 1;
}
}
return ptr[s];
};
int main() {
int size;
cout << "enter number \n";
cin >> size;
int* ptr = new int[size];
for (int l = 0; l <= size - 1; l++) {
cout << "enter number " << endl;
cin >> ptr[l];
}
cout << f(ptr, size) << endl;
delete[] ptr;
}
Your code has some bugs that need to be fixed
Do not ever use "using namespace std;"
Replace l <= size - 1 with l < size
There are more comparison problems. Fix them all
At the end of the function you have a ; Remove that.
In your function you use new, but not delete. Please delete your allocated memory.
The for loop for (int o = 0; o <= size; o++) { leads to an out of bounds desaster. Please change <= to <
In for (int os = 0; os < size; o++) { you have a typo. Please replace o++ with os++
Your software would then look like this:
#include <iostream>
int f(int ptr[], int size) {
int s = 0;
int* ptr2 = new int[size];
for (int y = 0; y < size; y++) {
ptr2[y] = 0;
}
for (int o = 0; o < size; o++) {
for (int os = 0; os < size; os++) {
if (ptr[o] == ptr[os]) ptr2[o]++;
}
}
int m;
for (int l = 0; l < size - 1; l++) {
m = ptr[0];
if (m < ptr2[l + 1]) {
s = l + 1;
}
}
delete[] ptr2;
return ptr[s];
};
int main() {
int size;
std::cout << "enter number \n";
std::cin >> size;
int* ptr = new int[size];
for (int l = 0; l < size; l++) {
std::cout << "enter number " << std::endl;
std::cin >> ptr[l];
}
std::cout << f(ptr, size) << std::endl;
delete[] ptr;
}
If you enable all compiler warnings, then you will already get some hints from clang
Additionally:
In C++ we do not use raw pointers for owned memory.
And, of course also not new and delete
Also. You should not use C-Style arrays in C++. Always use std::vector or std::array instead.
Use longer variable names
Write comments
Select an indentation style and use it consequently
By the way. With more advance C++ you could also write:
#include <iostream>
#include <utility>
#include <unordered_map>
#include <queue>
#include <vector>
#include <algorithm>
// Function to get most frequent used number in a vector
int topFrequent(std::vector<int>& numbers) {
// Count all occurences of numbers
std::unordered_map<int, size_t> counter{};
for (size_t i = 0; i < numbers.size(); i++) counter[numbers[i]]++;
// Waste some memory and sort
std::priority_queue<std::pair<int, int>> heap;
for (auto x : counter) heap.push(std::make_pair(x.second, x.first));
// Return most frequent number
return heap.top().second;
}
int main() {
// Instruct user what to do
std::cout << "How many numbers do you want to check? Please Enter a number: ";
// Get count of numbers to read
if (unsigned int count{}; (std::cin >> count) && (count > 0)) {
// Read all data
std::vector<int> data{};
std::cout << "\n\nPlease enter " << count << " values:\n";
std::copy_n(std::istream_iterator<int>(std::cin), count, std::back_inserter(data));
// Show result
std::cout << "\n\nMost frequent used number is: " << topFrequent(data) << "\n\n";
}
else std::cerr << "\n\nError: Problem with input\n\n";
}
To be compiled with C++17

MAX value of matrix and saving indexes in the same loop

I get a NxM sized matrix and I have to find the max value, the number of max values and the lines that contain it.
I tired using three for{for{}} loops, but it took too long. This method seems to work for small inputs, but when I try it with a 1000x1000 matrix, it finishes before it even takes all the input.
I realise this may be too much of a noob question, but I couldn't find anything else.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
int n, m;
int crnt{-51}, cnt{0};
cin >> n >> m;
int vekt[m];
int lines[n];
int inp;
for(int i=0; i<n; i++)
{
for(int p=0; p<m; p++)
{
cin >> vekt[p];
}
for(int j=0; j<m; j++)
{
if(vekt[j] == crnt)
{
lines[cnt] = i + 1;
cnt += 1;
}
if(vekt[j] > crnt)
{
crnt = vekt[j];
lines[0] = i + 1;
cnt = 1;
}
}
}
cout << cnt;
for(int i=0; i<cnt; i++)
{
cout << " " << lines[i];
}
return 0;
}
EDIT : not using vector or [n] was just easier... I simply saved it to a variable and used a bool:
int main()
{
int n, m;
int crnt{-51}, cnt{0};
cin >> n >> m;
int vekt[m];
int lines[n];
int inp;
bool inLine;
inLine = false;
for(int i=0; i<n; i++)
{
inLine = false;
for(int j=0; j<m; j++)
{
cin >> inp;
if(inp == crnt && inLine == false)
{
lines[cnt] = i + 1;
cnt += 1;
inLine = true;
}
if(inp > crnt)
{
crnt = inp;
lines[0] = i + 1;
cnt = 1;
}
}
}
cout << cnt;
for(int i=0; i<cnt; i++)
{
cout << " " << lines[i];
}
return 0;
}
This cut the time by enough so that I went under the limit.
int vekt[m]; is not standard C++, it is a variable length array (which some compilers allow as extension). Use std::vector instead.
That would also fix the bug you currently have: If cnt >= n (i.e. if you find more maxima than the matrix has lines), you will go out of bounds of lines and your program will most likely crash (although anything could happen), which is more likely to happen with larger matrices.
You can do this instead:
Declaration and initialization:
std::vector<int> linesWithMaxima;
When you find another value equal to the current maximum:
linesWithMaxima.push_back(i+1);
When you find a new maximum (larger than current):
linesWithMaxima.clear();
linesWithMaxima.push_back(i+1);
Note that this will list a line with multiple (identical) maxima multiple times. If you want to avoid duplicates, you can either check that you have not already added the current line (linesWithMaxima.back() != i+1) or use std::sort, std::unique and std::vector::erase.
Other than that your code looks fine. I would recommend naming the loop indices better (line instead of i etc.) and possibly merging the p and j loop because separating them seems to have no purpose. And if you want the most negative integer, use std::numeric_limits<int>::lowest().
Check this realization, without STL and vectors:
void input_matrix(int **&matrix, int &lines, int &columns)
{
int m = 0, n = 0;
cout << "input lines count:";
cin >> m;
cout << "input rows count:";
cin >> n;
matrix = new int *[m];
for(int i = 0;i < m;i++)
matrix[i] = new int[n];
cout << endl << "input matrix:" << endl;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
cin >> matrix[i][j];
lines = m;
columns = n;
}
void print_matrix(int **&matrix, int &lines, int &columns)
{
for(int i = 0; i < lines; i++)
{
for(int j = 0; j < columns; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
}
int find_max(int **matrix, int lines, int columns, int &max_count)
{
int max = INT_MIN;
max_count = 0;
for(int i = 0; i < lines; i++)
for(int j = 0; j < columns; j++)
{
if(matrix[i][j] > max)
{
max = matrix[i][j];
max_count = 1;
}
else
if(matrix[i][j] == max)
++max_count;
}
return max;
}
int main()
{
int **matrix = nullptr;
int m=0, n=0, count=0;
input_matrix(matrix, n, m);
cout << endl;
print_matrix(matrix, n, m);
cout << endl;
int max = find_max(matrix, n, m, count);
cout << "max=" << max << " count=" << count << endl;
for(int i = 0; i < n; i++)
delete[]matrix[i];
delete []matrix;
}
As requested by mister Max Langhof I would also like to propose a more modern solution, based on the std::vector container, which does not need pointers and manual memory management. It's a simple class matrix:
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdint>
using namespace std;
class matrix
{
private:
vector<vector<int>> m_data;
public:
matrix(int cols, int rows)
{
m_data.resize(cols);
for(auto &r : m_data)
r.resize(rows);
}
int max_element()
{
int max = INT_MIN;
for(auto &row: m_data)
{
auto maxinrow = *std::max_element(row.begin(), row.end());
if(maxinrow > max)
max = maxinrow;
}
return max;
}
int element_count(int elem)
{
int count = 0;
for(auto &row : m_data)
count += std::count_if(row.begin(), row.end(), [elem](int a){return a == elem;});
return count;
}
friend istream& operator>>(istream &os, matrix &matr);
friend ostream& operator<<(ostream &os, matrix &matr);
};
Input and output operators could be realized like this:
istream& operator>>(istream &os, matrix &matr)
{
for(int i = 0; i < matr.m_data.size(); i++)
{
for(int j = 0; j < matr.m_data[i].size(); j++)
cin >> matr.m_data[i][j];
cout << endl;
}
return os;
}
ostream& operator<<(ostream &os, matrix &matr)
{
for(int i = 0; i < matr.m_data.size(); i++)
{
for(int j = 0; j < matr.m_data[i].size(); j++)
cout << matr.m_data[i][j] << " ";
cout << endl;
}
return os;
}
And a sample of using of this matrix:
int main()
{
int m = 5, n = 4;
matrix matr(m, n);
cout << "input matrix:" << endl;
cin >> matr;
cout << endl << matr;
int max = matr.max_element();
cout << "max: " << max << " count:" << matr.element_count(max) << endl;
}
Checkout something like this
#include <iostream>
#include <set>
#include <vector>
int main() {
int rowsNo, columnsNo;
std::cin >> rowsNo >> columnsNo;
std::vector<int> matrix(rowsNo*columnsNo);
//Creating matrix
for(auto row = 0; row < rowsNo; ++row) {
for (auto column = 0; column < columnsNo; ++column)
std::cin >> matrix[row*columnsNo + column];
}
auto maxValue = -51;
//Finding positions of maximums
std::set<int> linesWithMaxValue;
for (auto position = 0; position < matrix.size(); ++position) {
if(matrix[position] == maxValue)
linesWithMaxValue.insert(position / columnsNo);
else if(matrix[position] > maxValue) {
linesWithMaxValue.clear();
maxValue = matrix[position];
linesWithMaxValue.insert(position / columnsNo);
}
}
//Print info
const auto numberOfMaxValues = linesWithMaxValue.size();
std::cout << "Number of maxiums: " << numberOfMaxValues << std::endl;
std::cout << "Lines that contains maximum:";
for (const auto& lineId : linesWithMaxValue)
std::cout << " " << lineId;
return 0;
}

After printing a random two dimensional array , I need to find the first min and first max in the first row?

For example, we have a random 5 x 5 array
1 5 9 4 2 <===== //need to find min and max in this row .
6 4 3 7 9----------- //and then swap their index columns
9 4 6 2 5
2 7 8 5 9
4 1 9 7 7
In the above array we need to look at the first row and find min and max , And then change their columns.
So the min and max in the first row are 1 and 9 and the answer should be
9 5 1 4 2
3 4 6 7 9
6 4 9 2 5
8 7 2 5 9
9 1 4 7 7
The columns swapped are highlighted .
I have tried to solve this problem with the the following code .
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
int array[5] = {0,0,0,0,0};
int max = array[0];
int min = array[0];
int indexOfMax = 0;
int indexOfMin = 0;
int n, m;
cout << "n = "; cin >> n;
cout << "m = "; cin >> m;
int **array = new int *[n]; // for the output of a random array
for(int i = 0; i < n; i++)
array[i] = new int [m];
srand((unsigned int)time(NULL));
for(int i = 0; i < n; i++){ // loop for the array
for(int j = 0; j < m; j++){
array[i][j] = rand() % 20;
cout << array[i][j] << " ";
if(array[i] > max) // finding the max in first row
{
max = array[i];
indexOfMax = i;
}
if(array[i] < min) // finding the min in the first row
{
min = indexOfMin;
indexOfMin = i;
}
cout << indexOfMin << " " << indexOfMax << endl;
}
}
cout << '\n';
}
return 0;
}
So, primarily I get this main.cpp:16:11: error: conflicting declaration ‘int** array’. And then i would like to know how to swap the columns of min and max ?
You don't need the extra array which you have mentioned in the code.
Working solution:
#include <iostream>
#include <time.h>
#include <limits.h>
using namespace std;
int main()
{
int max = INT_MIN;
int min = INT_MAX;
int indexOfFirstRowMax;
int indexOfFirstRowMin;
int n, m;
cout << "n = "; cin >> n;
cout << "m = "; cin >> m;
int **array = new int *[n]; // for the output of a random array
for(int i = 0; i < n; i++)
array[i] = new int[m];
srand((unsigned int)time(NULL));
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
array[i][j] = rand() % 20;
cout << array[i][j] << " ";
if(i==0)
{
if(array[i][j] > max) // finding the max in first row
{
max = array[i][j];
indexOfFirstRowMax = j;
}
if(array[i][j] < min) // finding the min in the first row
{
min = array[i][j];
indexOfFirstRowMin = j;
}
}
}
cout<<endl;
}
cout<<"indexOfFirstRowMin = "<<indexOfFirstRowMin<<endl;
cout<<"indexOfFirstRowMax = "<<indexOfFirstRowMax<<endl;
for(int i=0; i<n; i++)
{
int temp = array[i][indexOfFirstRowMin];
array[i][indexOfFirstRowMin] = array[i][indexOfFirstRowMax];
array[i][indexOfFirstRowMax] = temp;
}
cout<<"Output after interchanging the columns"<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cout<<array[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
#include <cstddef> // std::size_t
#include <cstdlib> // std::srand(), std::rand()
#include <ctime> // std::time()
#include <utility> // std::swap()
#include <iostream> // std::cout, std::cin
#include <iomanip> // std::setw()
int main()
{
// seed the old, rusty, low entropy random number generator
std::srand(static_cast<unsigned>(std::time(nullptr)));
std::cout << "rows = ";
std::size_t rows; // name variables with actual names instead of letters
std::cin >> rows; // to make them less prone to confusions
std::cout << "columns = ";
std::size_t columns; // declare variables as close to where they're used
std::cin >> columns; // as possible
int **array = new int *[rows]; // allocate the row pointers of our jagged array
for (size_t row{}; row < rows; ++row) {
array[row] = new int[columns];
for (size_t col{}; col < columns; ++col) {
array[row][col] = rand() % 20; // fill the array with random numbers 0...19
std::cout << std::setw(2) << array[row][col] << " "; // and also print them
}
std::cout.put('\n'); // add a newline after every row
}
std::cout.put('\n');
std::size_t max_index{};
std::size_t min_index{};
// find the indexes of the maximum and the minimum in the 1st row:
// As suggested by Some programmer dude in the comments you could
// (and should) use std::minmax_element() ... but i guess thats some
// assignment that wants you to do it on foot.
for (size_t col{ 1 }; col < columns; ++col) {
if (array[0][col] > array[0][max_index])
max_index = col;
if (array[0][col] < array[0][min_index])
min_index = col;
}
// print them
std::cout << "min = " << array[0][min_index] << ", max = " << array[0][max_index] << '\n';
// swap the column min_index with the column max_index:
for (size_t row{}; row < rows; ++row)
std::swap(array[row][min_index], array[row][max_index]);
// print it again:
for (size_t row{}; row < rows; ++row) {
for (size_t col{}; col < columns; ++col)
std::cout << std::setw(2) << array[row][col] << " ";
delete[] array[row]; // and in the process clean up the mess we made
std::cout.put('\n');
}
std::cout.put('\n');
delete[] array; // delete array of row pointers
}
Using the standard library facilities as suggested in my comment, you could implement it something like this:
#include <iostream>
#include <vector>
#include <iterator>
#include <random>
#include <algorithm>
int main()
{
int n, m;
std::cout << "n = ";
std::cin >> n;
std::cout << "m = ";
std::cin >> m;
// Creates a matrix of N x M elements
std::vector<std::vector<int>> array(n, std::vector<int>(m));
// Create a random-number generator for the range 1 to 20 (inclusive)
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 20);
// Generate random numbers filling our matrix
for (auto& v : array)
{
std::generate(begin(v), end(v), [&]() { return dis(gen); });
}
// Print the matrix before swapping
for (auto const& v : array)
{
std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
// Find the min/max of the first row in the matrix
auto minmax_pair = std::minmax_element(begin(array[0]), end(array[0]));
// From the pair of min/max iterators fetched above, get the indexes
auto min_index = std::distance(begin(array[0]), minmax_pair.first);
auto max_index = std::distance(begin(array[0]), minmax_pair.second);
// Now swap the columns of the min and max
for (auto& v : array)
{
std::swap(v[min_index], v[max_index]);
}
// Print the matrix after swapping
std::cout << '\n';
for (auto const& v : array)
{
std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
}

New set of values for testcases using srand() in c++

I am trying to create some test cases for my 'minimum dot product' problem. I want 10 test cases , each generating different set of values for both vector a and b.
The Problem is that even after using srand( time( NULL ) ) though a new input is generated every time I compile and run the code but that same input is used for all the 10 test cases.
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using std::vector;
void sort_asc(vector<int> &manav, int sizes)
{
int temp = 0;
for (int i = 0; i<sizes; i++)
{
for (int j = i + 1; j<sizes; j++)
{
if (manav[i] > manav[j])
{
temp = manav[i];
manav[i] = manav[j];
manav[j] = temp;
}
}
}
std::cout << "b in asc order : ";
for (int i = 0; i<sizes; i++)
{
std::cout << manav[i] << " ";
}
std::cout << std::endl;
}
void sort_desc(vector<int> &manav, int sizes)
{
int temp = 0;
for (int i = 0; i<sizes; i++)
{
for (int j = i + 1; j<sizes; j++)
{
if (manav[i] < manav[j])
{
temp = manav[i];
manav[i] = manav[j];
manav[j] = temp;
}
}
}
std::cout << "a in desc : ";
for (int i = 0; i<sizes; i++)
{
std::cout << manav[i] << " ";
}
std::cout << std::endl;
}
long long min_dot_product(vector<int> a, vector<int> b, int sizes) {
long long result = 0;
sort_desc(a, sizes);
sort_asc(b, sizes);
for (size_t i = 0; i < sizes; i++) {
result += a[i] * b[i];
}
return result;
}
int main() {
srand(time(NULL));
/*
std::cin >> n;
vector<int> a(n), b(n);
for (size_t i = 0; i < n; i++) {
std::cin >> a[i];
}
for (size_t i = 0; i < n; i++) {
std::cin >> b[i];
}
*/
//================================================================ TESTING =========================================================================
int z = 0;
int n = (rand() % 10) + 1; // generating the size of the vectors [1-10]
std::cout << "n = " << n << "\n";
vector<int> a;
vector<int> b;
while (z != 10) {
for (int i = 0; i < n; ++i)
{
int p = (rand() % 10) - 5;
a.push_back(p); // input values [-5,4] in 'a'
}
std::cout << "Unsorted Vector a = ";
for (int i = 0; i<n; i++)
{
std::cout << a[i] << " ";
}
std::cout << std::endl;
for (int i = 0; i < n; ++i)
{
int q = (rand() % 10) - 5;
b.push_back(q); // inputing values [-5,4] in 'b'
}
std::cout << "Unsorted Vector b = ";
for (int i = 0; i<n; i++)
{
std::cout << b[i] << " ";
}
std::cout << std::endl;
std::cout << "min_dot_product = " << min_dot_product(a, b, n) << std::endl;
z++;
}
return 0;
}
I somehow want to generate a different set of values for vector a and b for all of the 10 test cases every time I run the code.
I have tried srand(i) within the respective for loops before pushing the value in vectors but its not working for me, also reusing srand( time( NULL ) ) within the for loops is not gonna help either. Is there some other simple way I can achieve this?
The problem is you never clear out the vector on each iteration. Since you don't all of the new random numbers you generate are being added to the end of the vector and you ignore them since n never changes.
What you need to do is add
a.clear();
b.clear();
to the end of the while loop. This will clear out the vectors and then when you start the next iteration the new random numbers will get added into the part of the vector you use in your functions.
You could also set the vector the proper size and then use [] to access the elements. This way you would just overwrite the previous values and you would not have to call clear()
vector<int> a(n);
vector<int> b(n);
//...
for (int i = 0; i < n; ++i)
{
a[i] = (rand() % 10) - 5;
b[i] = (rand() % 10) - 5;
}
I put both assignments in the same for loop to save space. You can do this in two separate loops but it is not needed.