I am having a hard time with translating this pseudocode into C++. The goal is to generate random numbers into A[] and sort them using insertion sort then get the execution time in milliseconds. Insertion sort would run for m=5 times. Each n value should be 100, 200, 300,....,1000. So for example if n=100 then that would run 5 times with 5 different sets of random numbers, then do the same thing for n=200, etc...
I have already written my insertion sort and that works so I did not include it. I am really just having trouble translating this pseudocode into something I can work with. I included my attempt and the pseudocode so you can compare.
Pseudocode:
main()
//generate elements using rand()
for i=1 to 5
for j=1 to 1000
A[i,j] = rand()
//insertion sort
for (i=1; i<=5; i=i+1)
for (n=100; n<=1000; n=n+100)
B[1..n] = A[i,n]
t1 = time()
insertionSort(B,n)
t2 = time()
t_insort[i,n] = t2-t1
//compute the avg time
for (n=100; n<=1000; n=n+100)
avgt_insort[n] = (t_insort[1,n]+t_insort[2,n]+t_insort[3,n]+...+t_insort[5,n]+)/5
//plot graph with avgt_insort
This is my attempt:
I am confused with t_insort and avgt_insort, I did not write them to C++. Do I make these into new arrays? Also take I am not sure if I am doing my time correctly either. I am sorta new at this running time thing so I have never actually wrote it into code yet.
#include <iostream>
#include <stdlib.h>
#include <time.h>
int main()
{
int A[100];
for(int i=1; i<=5; i++)
{
for(int j=1; j<=1000; j++)
{
A[i,j] = rand();
}
}
for(int i=0;i<=5; i++)
{
for(int n=100; n<=1000; n=n+100)
{
static int *B = new int[n];
B[n] = A[i,n];
cout << "\nLength\t: " << n << '\n';
long int t1 = clock();
insertionSort(B, n);
long int t2 = clock();
//t_insort
cout << "Insertion Sort\t: " << (t2 - t1) << " ms.\n";
}
}
for(int n=100; n<=1000; n=n+100)
{
//avt_insort[n]
}
return 0;
}
The pseudocode is relatively close to a C++ code with some syntactic changes. Note that this C++ code is a straightforward "translation". A better solution would be to use containers from C++ standard library.
int main()
{
int A[6][1001], B[1001]; //C++ starts indexing from 0
double t_insort[6][1000]; //should be of return type of time(), so maybe not double
int i,j,n;
for( i=1;i<=5;i++) //in C++ it is more common to start from 0 for(i=0;i<5;i++)
for(j=1;j<=1000;j++)
A[i][j] = rand(); //one has to include appropriate header file with rand()
//or to define his/her own function
for (i=1; i<=5; i++)
for (n=100; n<=1000; n=n+100)
{
B[n]=A[i][n];
t1 = time(); //one has firstly to declare t1 to be return type of time() function
insertionSort(B,n); //also this function has to be defined before
t2=time();
t_insort[i][n]=t2-t1; //this may be necessary to change depending on exact return type of time()
}
}
for (n=100; n<=1000; n=n+100)
for(i=1;i<=5;i++)
avgt_insort[n] += t_insort[i][n]
avgt_insort[n]/=5;
//plot graph with avgt_insort
A[i,j] is the same as A[j] (comma operator!), and wouldn't work.
You might want to declare a two dimensional array for A or even better an appropriate std::array:
int A[100][1000];
std::array<std::array<int,1000>, 100> A; // <- prefer this for c++
Also allocating B right away inside the for loop doesn't look right:
static int *B = new int[n];
and
B[n] = A[i,n];
won't work either as you intend (see above!).
Related
I've written some code in c++ that is meant to find the minimum and maximum values that can be calculated by summing 4 of the 5 integers presented in an array. My thinking was that I could add up all elements of the array and loop through subtracting each of the elements to figure out which subtraction would lead to the smallest and largest totals. I know this isn't the smartest way to do it, but I'm just curious why this brute force method isn't working when I code it. Any feedback would be very much appreciated.
#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
void minimaxsum(vector<int> arr){
int i,j,temp;
int n=sizeof(arr);
int sum=0;
int low=INT_MAX;
int high=0;
for (j=0;j<n;j++){
for (i=0;i<n;i++){
sum+=arr[i];
}
temp=sum-arr[j];
if(temp<low){
low=temp;
}
else if(temp>high){
high=temp;
}
}
cout<<low;
cout<<high<<endl;
}
int main (){
vector<int> arr;
arr.push_back(1.0);
arr.push_back(2.0);
arr.push_back(3.0);
arr.push_back(1.0);
arr.push_back(2.0);
minimaxsum(arr);
return 0;
}
There are 2 problems.
Your code is unfortunately buggy and cannot deliver the correct result.
The solution approach, the design is wrong
I will show you what is wrong and how it could be refactored.
But first and most important: Before you start coding, you need to think. At least 1 day. After that, take a piece of paper and sketch your solution idea. Refactor this idea several times, which will take a complete additional day.
Then, start to write your code. This will take 3 minutes and if you do it with high quality, then it takes 10 minutes.
Let us look first at you code. I will add comments in the source code to indicate some of the problems. Please see:
#include <iostream>
#include <vector>
#include <limits.h> // Do not use .h include files from C-language. Use limits
using namespace std; // Never open the complete std-namepsace. Use fully qualified names
void minimaxsum(vector<int> arr) { // Pass per reference and not per value to avoid copies
int i, j, temp; // Always define variables when you need them, not before. Always initialize
int n = sizeof(arr); // This will not work. You mean "arr.size();"
int sum = 0;
int low = INT_MAX; // Use numeric_limits from C++
int high = 0; // Initialize with MIN value. Otherwise it will fail for negative integers
for (j = 0; j < n; j++) { // It is not understandable, why you use a nested loop, using the same parameters
for (i = 0; i < n; i++) { // Outside sum should be calculated only once
sum += arr[i]; // You will sum up always. Sum is never reset
}
temp = sum - arr[j];
if (temp < low) {
low = temp;
}
else if (temp > high) {
high = temp;
}
}
cout << low; // You miss a '\n' at the end
cout << high << endl; // endl is not necessary for cout. '\n' is sufficent
}
int main() {
vector<int> arr; // use an initializer list
arr.push_back(1.0); // Do not push back doubles into an integer vector
arr.push_back(2.0);
arr.push_back(3.0);
arr.push_back(1.0);
arr.push_back(2.0);
minimaxsum(arr);
return 0;
}
Basically your idea to subtract only one value from the overall sum is correct. But there is not need to calculate the overall sum all the time.
Refactoring your code to a working, but still not an optimal C++ solution could look like:
#include <iostream>
#include <vector>
#include <limits>
// Function to show the min and max sum from 4 out of 5 values
void minimaxsum(std::vector<int>& arr) {
// Initialize the resulting values in a way, the the first comparison will always be true
int low = std::numeric_limits<int>::max();
int high = std::numeric_limits<int>::min();;
// Calculate the sum of all 5 values
int sumOf5 = 0;
for (const int i : arr)
sumOf5 += i;
// Now subtract one value from the sum of 5
for (const int i : arr) {
if (sumOf5 - i < low) // Check for new min
low = sumOf5 - i;
if (sumOf5 - i > high) // Check for new max
high = sumOf5 - i;
}
std::cout << "Min: " << low << "\tMax: " << high << '\n';
}
int main() {
std::vector<int> arr{ 1,2,3,1,2 }; // The test Data
minimaxsum(arr); // Show min and max result
}
I was trying to solve this question
but codechef.com says the answer is wrong.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t, n, diff, mindiff;
cin >> t;
cin >> n;
int val[n];
while(t--)
{
mindiff = 1000000000;
for(int i = 0; i<n; i++)
{
cin >> val[i];
}
int a = 0;
for(a = 0; a<n ; a++)
{
for(int b=a+1; b<n ; b++)
{
diff = abs(val[a] - val[b]);
if(diff <= mindiff)
{
mindiff = diff;
}
}
}
cout << mindiff << endl;
}
return 0;
}
The results are as expected (for at least the tests I did) buts the website says its wrong.
There are a few things in your code that you should change:
Use std::vector<int> and not variable-length arrays (VLA's):
Reasons:
Variable length arrays are not standard C++. A std::vector is standard C++.
Variable length arrays may exhaust stack memory if the number of entries is large. A std::vector gets its memory from the heap, not the stack.
Variable length arrays suffer from the same problem as regular arrays -- going beyond the bounds of the array leads to undefined
behavior. A std::array has an at() function that can check boundary access when desired.
Use the maximum int to get the maximum integer value.
Instead of
mindif = 1000000000;
it should be:
#include <climits>
//...
int mindiff = std::numeric_limits<int>::max();
As to the solution you chose, the comments in the main section about the nested loop should be addressed.
Instead of a nested for loop, you should sort the data first. Thus finding the minimum value between two values is much easier and with less time complexity.
The program can look something like this (using the data provided at the link):
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
int main()
{
int n = 5;
std::vector<int> val = {4, 9, 1, 32, 13};
int mindiff = std::numeric_limits<int>::max();
std::sort(val.begin(), val.end());
for(int a = 0; a < n-1 ; a++)
mindiff = std::min(val[a+1] - val[a], mindiff);
std::cout << mindiff;
}
Output:
3
To do this you can use a simple for():
// you already have an array called "arr" which contains some numbers.
int biggestNumber = 0;
for (int i = 0; i < arr.size(); i++) {
if (arr[i] > biggestNumber) {
biggestNumber = arr[i];
}
}
arr.size will get the array's length so that you can check every value from the position 0 to the last one which is arr.size() - 1 (because arrays are 0 based in c++).
Hope this helps.
I have looked and looked and am still lost on how to copy or get elements from an array and put them into new arrays ( divide and conquer is the goal).
I have an array that generates 100 random numbers. I need to split the random numbers into 4 smaller arrays obviously containing 25 elements and not have any duplicates. I have read about using pointers, but honestly I don't understand why even use a pointer. Why do I care about another variables address?
I don't know how to do this. Here is my code so far:
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
// Seed the random number generator
srand(time(NULL));
//create an array to store our random numbers in
int Orignumbers[100] = {};
// Arrays for the divide and conquer method
int NumbersA [25] = {};
int NumbersB [25] = {};
int NumbersC [25] = {};
int NumbersD [25] = {};
//Generate the random numbers
for(int i =0; i < 100; i++)
{
int SomeRandomNumber = rand() % 100 + 1;
// Throw random number into the array
Orignumbers[i] = SomeRandomNumber;
}
// for(int i = 0; i < ) started the for loop for the other arrays, this is where I am stuck!!
// Print out the random numbers
for(int i = 0; i < 100; i++)
{
cout << Orignumbers[i] << " , ";
}
}
"divide and conquer" is rather easy; when copying into NumbersA and so forth, you just have to access your Originnumbers with a proper offset, i.e. 0, 25, 50, and 75:
for(int i = 0; i < 25; i++) {
NumbersA[i] = Orignumbers[i];
NumbersB[i] = Orignumbers[i+25];
NumbersC[i] = Orignumbers[i+50];
NumbersD[i] = Orignumbers[i+75];
}
The thing about "no duplicates" is a little bit more tricky. Generating a random sequence of unique numbers is usually solved through "shuffling". Standard library provides functions for that:
#include <random>
#include <algorithm>
#include <iterator>
#include <vector>
int main()
{
std::random_device rd;
std::mt19937 g(rd());
int Orignumbers[100];
//Generate the random numbers without duplicates
for(int i =0; i < 100; i++) {
Orignumbers[i] = i+1;
}
std::shuffle(Orignumbers, Orignumbers+100, g);
// Arrays for the divide and conquer method
int NumbersA [25] = {};
int NumbersB [25] = {};
int NumbersC [25] = {};
int NumbersD [25] = {};
for(int i = 0; i < 25; i++) {
NumbersA[i] = Orignumbers[i];
NumbersB[i] = Orignumbers[i+25];
NumbersC[i] = Orignumbers[i+50];
NumbersD[i] = Orignumbers[i+75];
}
// Print out the random numbers
for(int i = 0; i < 100; i++)
{
cout << Orignumbers[i] << " , ";
}
}
Problem:
The program can't be guaranteed to have no duplicate value as the rand() function can generate any random sequence and that may include the decimal value of 99 for 99 times though probability is very low but chances are.
Example:
for(loop=0; loop<9; loop++)
printf("%d", Rand()%10);
If looped for 10 times, it may result some values like:
Output: 6,1,1,1,2,9,1,3,6,9
Compiled Successfully:
Hence, no certainity that values won't repeat
Possibly Solution:
There could be a solution where you can place the values in OriginalArray and compare the rand() generate values against the OriginalArray values.
For first iteration of loop, you can directly assign value to OriginalArray then from 2nd iteration of loop you've to compare rand() value against OriginalArray but insertion time consumption may be higher than O(NN) as rand() function may repeat values.
Possibly Solution:
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
int Orignumbers[100] ;
int NumbersA [25] ,
NumbersB [25] ,
NumbersC [25] ,
NumbersD [25] ;
srand(time(NULL));
for(int i =0; i < 100; i++){
Orignumbers[i] = rand() % 100+1;
for(int loop=0; loop<i; loop++) {
if(Orignumber[loop] == Orignumber[i] ) {
i--;
break;
}
}
}
//Placing in four different arrays thats maybe needed.
for(int i = 0; i <25; i++ ) {
NumbersA[i] = Orignumbers[i];
NumbersB[i] = Orignumbers[i+25];
NumbersC[i] = Orignumbers[i+50];
NumbersD[i] = Orignumbers[i+75];
}
for(int i = 0; i < 99; i++)
cout << Orignumbers[i] << " , ";
}
As you tagged your question with C++ then forget about old-fashion arrays, let's do it C++ style.
You want to split your array into 4 arrays and they should not have duplicate numbers, so you can't have a number 5 times in your original array, because then surely one of your 4 arrays will have a duplicate one, So here is the way I propose to do it :
#include <set>
#include <ctime>
#include <vector>
int main() {
std::multiset<int> allNums;
std::srand(unsigned(std::time(0)));
for (int i = 0; i < 100; ++i) {
int SomeRandomNumber = std::rand() % 100 + 1;
if (allNums.count(SomeRandomNumber) < 4) {
allNums.insert(SomeRandomNumber);
}
else {
--i;
}
}
std::vector<int> vOne, vTwo, vThree, vFour;
for (auto iter = allNums.begin(); iter != allNums.end(); ++iter) {
vOne.push_back(*iter);
++iter;
vTwo.push_back(*iter);
++iter;
vThree.push_back(*iter);
++iter;
vFour.push_back(*iter);
}
system("pause");
return 0;
}
EDIT : As you mentioned in the comments, you just want to find a number in an array, so how about this :
for (int i = 0; i < 100; ++i) {
if (origArray[i] == magicNumber) {
cout << "magicNumber founded in index " << i << "of origArray";
}
}
On some situations, even on C++, the use of arrays might be preferable than vectors, for example, when dealing with multidimensional arrays (2D, 3D, etc) that needs to be continuous and ordered on the memory. (e.g. later access by other applications or faster exporting to file using formats such as HDF5.)
Like Jesper pointed out, you may use Copy and I would add MemCopy to copy the content of an array or memory block into another.
Don't underestimate the importance of pointers, they may solve your problem without the need doing any copy. A bit like Stephan solution but without the need of the index variable "i", just having the pointers initialized at different places on the array. For a very large number of elements, such strategy will save some relevant processing time.
This question already has answers here:
rand() returns same values when called within a single function
(5 answers)
Closed 8 years ago.
I'm trying to write a simple function that generates an array with random integers.
I encountered with an interesting thing, when I run this program outputs -each cout
statements- seem the same.
However, when I am debugging and watching it step by step array values are changing.
Am I doing something wrong?
Thanks.
void generateRandomArray( int *&inputArray, int size){
if(inputArray != NULL){
delete []inputArray;
}
//create a new array
inputArray = new int [size];
//fill with random numbers
srand(unsigned (time (NULL)));
for (int i = 0; i < size ; i++)
inputArray[i] = (rand() % 100) ;
}
int main(){
//Variables
int *inputArray = NULL;
int size;
//Test
size = 10;
//first call
generateRandomArray( inputArray, size);
for(int i = 0 ; i < size; i++){
cout << inputArray[i] << endl;
}
cout << "------------------" << endl;
//second call
generateRandomArray( inputArray, size);
//output is the same with previous
for(int i = 0 ; i < size; i++){
cout << inputArray[i] << endl;
}
return 0;
}
The program runs too fast, srand(unsigned (time (NULL))); will get a seed having the same seconds (since epoch). Hence, the rand sequences are the same.
The problem is that if the calls to srand all happen withing the same second, the generator will be seeded with the same values and so generate the same sequence, always.
When you're debugging it will be slower, and allow time to pass and have different seed for the generator. When not debugging the time between calls will be too fast.
Don't call srand more than once, unless you know what you're doing. Put it at the start of the main function, and don't call it again.
Call srand(time(NULL)) and it will seed the current time and make a random number from it. Since time is changing all the time, it will give you a different number every time.
With C++11, you may use something like: (https://ideone.com/EIb0nY)
#include <iostream>
#include <random>
#include <vector>
std::vector<int> generateRandomArray(std::default_random_engine& generator, int size)
{
std::uniform_int_distribution<int> distribution(1, 100);
std::vector<int> res(size);
for (auto& e : res) {
e = distribution(generator);
}
return res;
}
int main()
{
std::default_random_engine generator;
const int size = 10;
//first call
for (auto e : generateRandomArray(generator, size)) {
std::cout << e << std::endl;
}
std::cout << "------------------" << std::endl;
//second call
for (auto e : generateRandomArray(generator2, size)) {
std::cout << e << std::endl;
}
return 0;
}
That use the new random facilities.
It avoids manual memory management (with std::vector).
I use clock() in library to calculate excution time of a function, which is BubbleSort(..) function in my code below. But probleam is that the return execution time always = 0 (and it shows no unit, too).
This is my code:
#include <iostream>
#include <ctime>
using namespace std;
void BubbleSort(int arr[], int n)
{
for (int i = 1; i<n; i++)
for (int j = n-1; j >=i; j-- )
if (arr[j] < arr[j-1])
{
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
return;
}
int main()
{
int arr[] = {4,1,7,2,6, 17, 3, 2, 8,1};
int len = sizeof(arr)/sizeof(int);
cout << "Before Bubble Sort: \n";
for (int i=0;i<len;i++)
{
cout << arr[i] << " ";
}
clock_t start_s=clock(); // begin
BubbleSort(arr,len);
clock_t stop_s=clock(); // end
cout << "\nAfter Bubble Sort: \n";
for (int i=0;i<len;i++)
{
cout << arr[i] << " ";
}
// calculate then print out execution time - currently always returns 0 and I don't know why
cout << "\nExecution time: "<< (double)(stop_s - start_s)/CLOCKS_PER_SEC << endl;
//system("pause");
return 0;
}
I haven't known how to fix this problem yet .. So hope you guys can help me with this. Any comments would be very appreciated. Thanks so much in advanced !
As you have only a very small array, the execution time is probably much shorter than the resolution of clock(), so you either have to call the sort algorithm repeatedly or use another time source.
I modified your code as such and both start end stop have the value of 0. (ubuntu 13.10)
std::cout<<"start: "<<start_s<<std::endl;
BubbleSort(arr,len);
clock_t stop_s=clock(); // end
std::cout<<"stop: "<<stop_s<<std::endl;
you probably want something more like gettimeofday()
this http://www.daniweb.com/software-development/cpp/threads/120862/clock-always-returns-0 is an interesting discussion of the same thing. the poster concluded that clock()(on his machine) had a resolution of about 1/100 of a sec. and your code is probably ( almost certainly) running faster than that