New set of values for testcases using srand() in c++ - 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.

Related

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

How do I put any value X after all the minimums in an array?

If I enter an array , at first the code finds the minimums then I want to put zeroes after all the minimums . For example
given an array = 1,1,3,1,1
As we see 1s are the minimum so the result should be = 1,0,1,0,3,1,0,1,0
CODE
#include <pch.h>
#include <iostream>
int main()
{
int min = 10000;
int n;
std::cout << "Enter the number of elements (n): "; //no of elements in the
std::cin >> n; //array
int *array = new int[2 * n];
std::cout << "Enter the elements" << std::endl;
for (int i = 0; i < n; i++) {
std::cin >> array[i];
if (array[i] > min)
min = array[i];
}
for (int i = 0; i < n; i++) {
if (array[i] == min) { // Not very clear about this
for (int k = n; k > i; k--) // part of the code, my teacher
array[k] = array[k - 1]; //explained it to me , but i
array[i + 1] = 0; // didn't understand (from the
i++; // `for loop k` to be precise)
n++;
}
std::cout << array[i] << ", 0";
}
return 0;
}
But my answer doen't put zeroes exactly after minimums
There are few issues in your code, first of all your min is wrong. I have fixed your code with comments on fixes I have made. Please take a look :
#include "stdafx.h"
#include <iostream>
int main()
{
int min = 10000;
bool found = 0;
int n;
std::cout << "Enter the number of elements (n): "; //no of elements in the
std::cin >> n; //array
int *array = new int[2 * n];
std::cout << "Enter the elements" << std::endl;
for (int i = 0; i < n; i++) {
std::cin >> array[i];
if (array[i] < min) //< instead of >
min = array[i];
}
for (int i = 0; i < n; i++) {
if (array[i] == min)
{
for (int k = n; k > i; k--)
{
array[k] = array[k - 1];
}
array[i + 1] = 0;
i++; //increment i here because you don't want to consider 0 that you have just added above.
n++; //since total number of elements in the array has increased by one (because of 0 that we added), we need to increment n
}
}
//print the array separately
for (int i = 0; i < n; i++)
{
std::cout << array[i];
if (i != n - 1)
{
std::cout << ",";
}
}
return 0;
}
The first issue was in the calculation of min: < instead of >.
Another problem if that you are modifyng the paramers iand ninside the loop. This is rather dangerous and implies to be very cautious.
Another issue was that it should be i++; n++; instead of i--,n--;
Here is the code:
// #include <pch.h>
#include <iostream>
int main()
{
int min = 1000000;
int n;
std::cout << "Enter the number of elements (n): "; //no of elements in the
std::cin >> n; //array
int *array = new int[2 * n];
std::cout << "Enter the elements" << std::endl;
for (int i = 0; i < n; i++) {
std::cin >> array[i];
if (array[i] < min)
min = array[i];
}
for (int i = 0; i < n; i++) {
if (array[i] == min) { // Not very clear about this
for (int k = n; k > i; k--) // part of the code, my teacher
array[k] = array[k - 1]; //explained it to me , but i
array[i + 1] = 0; // didn't understand (from the)
i++;
n++;
}
}
for (int i = 0; i < n; i++) {
std::cout << array[i] << " ";
}
std::cout << "\n";
return 0;
}

Receiving memory-related runtime error & searching for tips on code efficiency

I compiled my code numerous times and receive a memory-related runtime error. I am new to programming and couldn't figure out the issue. If someone can assist me in understanding why this is occurring and give me a few tips on how to clean up my code/make it more efficient I would greatly appreciate it!
#include <iostream>
#include <cmath>
void chefsMenuitems();
void chefsMenuitems(int P[], int arr_size) {
int count = 0;
int current_item = 0;
int n = 0;
int i = 0;
for (int j = 0; j < arr_size; j++ ) {
while(P[j] > 0) {
for ( i = 0; current_item < P[j]; i++) {
current_item = pow(2,(i));
if (current_item > P[j]){
current_item = pow(2,(i - 1));
break;
}
}
P[j] = P[j] - current_item;
current_item = 0;
n++;
}
count++;
std::cout << "The number of menu items for price " << count << " are: " << n << "\n";
n = 0;
current_item = 0;
}
}
int main() {
int T = 0;
int P[] = {0};
int arr_size;
std::cout << "Please enter the number of test cases: \n";
std::cin >> T;
while(T < 1 || T > 5 ) {
std::cout << "Test cases must be between 1 & 5 inclusive: \n";
std::cin >> T;
}
arr_size = T;
for (int i = 0; i < T; i++) {
std::cout << "Please enter the amount you are willing to spend: \n";
std::cin >> P[i];
while(P[i] < 1 || P[i] > pow(10, 5)) {
std::cout << "The amount you are willing to spend must be between 1 and 10^5 inclusive: \n";
std::cin >> P[i];
}
}
chefsMenuitems(P, arr_size);
return 0;
}
Your
int P[] = { 0 };
is an array of one element but you try to access up to 5 elements.
Use a std::vector<int> if you want an array-like container with a size not known at compile-time or waste some space by defining an array of the largest possible size for expected input:
int P[5] = {};

Taking the elements that are > 0 from 1 array to another

I make the user to type maximum elements and then enter that elements into first array p,then I want to take only the elements that are bigger than 0 and transfer them to a new array w. Here's the code and where exactly I make mistake:
void main(){
int p[10], w[10], n,i,j;
cout << "Maximum elements: "; cin >> n;
for (i = 0; i < n; i++){
cout << "Enter " << i << "-nd element"; cin >> p[i];
}
j = 0;
for (i = 0; i < n; i++){
if (p[i] > 0){
w[j] = p[i];
j++;
}
for (j = 0; j < n; j++){
cout << w[j];
}
}
system("pause");
}
In:
for (i = 0; i < n; i++){
if (p[i] > 0){
w[j] = p[i];
j++;
}
for (j = 0; j < n; j++){
cout << w[j];
}
}
the inner loop is printing every element of the array w. That loop is executed for every element of p (being it inside the outer for loop).
This mean that, for example, the first time it visits p to check if the first element is 0, it may assign w[0] and then go on and print all the elements of w. Problem is that w is not initialised at that point, so what you see is random garbage (probably).
Just move the loop outside and make it so it only prints the part of the array that is populated:
for (i = 0; i < n; i++){
if (p[i] > 0){
w[j] = p[i];
j++;
}
}
for (int k = 0; k < j; k++){
cout << w[k];
}
Live demo
Also learn how to use std::vector or std::array and the algorithms in <algorithm>.
Also remember that main has return type int.
Using std::copy_if from <algorithm> do the job you want, as in the example provided in http://www.cplusplus.com/reference/algorithm/copy_if/:
// copy_if example
#include <iostream> // std::cout
#include <algorithm> // std::copy_if, std::distance
#include <vector> // std::vector
int main () {
std::vector<int> foo = {25,15,5,-5,-15};
std::vector<int> bar (foo.size());
// copy only positive numbers:
auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0);} );
bar.resize(std::distance(bar.begin(),it)); // shrink container to new size
std::cout << "bar contains:";
for (int& x: bar) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
For you code, the problem is that you modify j in the printing loop whereas it is primary used as output index. Try to reduce scope of your local variable to out spot those issues, creating sub function may also help.
Finnaly, your fixed code may be something like:
void main(){
std::cout << "Maximum elements: ";
int n;
std::cin >> n;
int p[10];
for (int i = 0; i < n; i++){
std::cout << "Enter " << i << "-nd element";
std::cin >> p[i];
}
int w[10];
int w_size = 0;
for (int i = 0; i < n; i++){
if (p[i] > 0){
w[w_size] = p[i];
w_size++;
}
}
for (int i = 0; i < w_size; i++){
std::cout << w[i];
}
system("pause");
}

Sorting an array (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.