random shuffle operation - c++

i have following code
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int a[] = {2, 1, 4, 3, 5, 6, 7, 9, 8, 10, 11};
int n = sizeof(a) / sizeof(int);
int k=0;
for (int i = 0; i < n; i++)
{
k = i + rand() % (n-1-i);
int s = a[i];
a[i] = a[k];
a[k] = s;
}
for (int i = 0; i < n; i++)
{
cout << a[i] << " " << endl;
}
return 0;
}
but it gives me runtime error,i know there is a lot of method in internet ,just i choose such simple for exam preparation in university,please help me what is wrong?

I think rand()%(n-1-i) will give you a divide-by-zero for certain values if i (like i == n-1).

You might want to ask yourself what the result of %(n-1-i) will be for all possible values of i.

n = 11. When i = 10, that's a k= i+rand() % 0;
Mod by zero is undefined and can operate a number of different ways. I've seen it equivalent to mod
infinity, so it would be returning k as i+rand() which would lead to your out-of-bounds error.

Related

How to find the maximum difference of an array and print the numbers that gave the difference?

I've been trying to get into coding and need some help with my code. I figured out how to get the maximum difference, but I also want to print the numbers used to get that difference. For example, a-b=diff, I want to print a, b, and diff separately. My friend also challenged me to get the smaller value first, then get the bigger value. Now, once I pick a certain element in the array as the smallest number, I'm only allowed to pick through the next elements for the biggest number. For example, if the array is {2, 3, 4, 15, 8, 1}, it should be 15 - 2, not 15 - 1.
Here is my code to get the maximum difference/what I have so far:
#include <iostream>
using namespace std;
int maximum_difference(int arr[], int n)
{
int max_num = arr[1];
int min_num = arr[0];
int max_difference = max_num - min_num;
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n; j++)
{
if (arr[j] - arr[i] > max_difference)
{
max_num=arr[j];
min_num=arr[i];
max_difference = max_num - min_num;
}
}
}
return max_difference;
}
int main()
{
int n;
cout<<"elements: ";
cin >> n;
int arr[n];
for(int i=0; i<n; i++)
{
cin >> arr[i];
}
cout << "Maximum difference is " << maximum_difference(arr, n);
return 0;
}
What should I add or replace, so that I could cout max_num and min_num together with the max_difference?
I will address the algorithm part of this. The C++ part doesn't interest me; once you see the solution you'll know why.
We must choose indices i and j such that i <= j and a[j] - a[i] is maximized.
Your example sequence:
a = [2, 3, 4, 15, 8, 1]
Find the incremental maximum values starting from the right. (Most readers will immediately get the rest of the solution given this one hint).
maxs = [15, 15, 15, 15, 8, 1]
Find the incremental minimum values starting from the left.
mins = [2, 2, 2, 2, 2, 1]
Subtract them to find the greatest possible differences.
diffs = [13, 13, 13, 13, 6, 0]
The maximum element in this array, 13 is the largest value of a[j] - a[i] possible.
To find the actual values of i and j we store the indices of our best value for i and indices for the corresponding best value for j.
bestj = [3, 3, 3, 3, 4, 5]
besti = [0, 0, 0, 0, 0, 5]
We can compute the best difference the same way as before, but indirectly via the indices. For each k, diffs[k] = a[bestj[k]] - a[besti[k]] which still produces the same diffs as before:
diffs = [13, 13, 13, 13, 6, 0]
And when we find the index of the maximum diff, any such index will do. There may be multiple solutions, but this will find one solution (values for i and j) that produces a maximal result. Suppose we identify index k as having the maximal value 13, theni = besti[k] and j = bestj[k].
And therefore one solution is i = 0 and j = 3.
confirm:
a = [2, 3, 4, 15, 8, 1]
^i ^^j
i = 0
j = 3
a[i] = 2
a[j] = 15
a[j] - a[i] = 13
So again, I'm not going to provide the code, but if you can write a loop to scan from right to left computing incremental maximums as you go (as shown above), then you can code it up easily.
You don't need to use two for loops for finding the max and min values of the array. Additionally, in Standard C++ the size of an array must be a compile-time constant. So when you wrote:
int n;
cin >> n;
int arr[n]; //NOT STANDARD C++
The statement int arr[n]; is not standard C++ since n is not a constant expression.
Better would be to use std::vector as shown below:
Method 1: Manually finding max and min values
#include <iostream>
#include <vector>
#include <climits>
//this function take a vector as input and returns the difference b/w max and min values
int maximum_difference(const std::vector<int>& arr)
{
int max_num = INT_MIN;
int min_num = INT_MAX;
//iterate through the vector to find the max and min value
for(const int& element: arr)
{
if(element > max_num)
{
max_num = element;
}
if(element < min_num)
{
min_num = element;
}
}
return max_num - min_num; //return the difference of mx and min value
}
int main()
{
int n;
std::cout<<"elements: ";
std::cin >> n;
//create vector of int of size n
std::vector<int> arr(n);
//take elements from user
for(int i=0; i<n; i++)
{
std::cin >> arr[i];
}
std::cout << "Maximum difference is " << maximum_difference(arr);
return 0;
}
Method 2: Using std::minmax_element to find the max and min values
Here we use std::minmax_element which returns a pair consisting of an iterator to the smallest element as the first element and an iterator to the greatest element as the second.
#include <iostream>
#include<vector>
#include<algorithm>
int main()
{
int n;
std::cout<<"elements: ";
std::cin >> n;
//create vector of int of size n
std::vector<int> arr(n);
//take elements from user
for(int i=0; i<n; i++)
{
std::cin >> arr[i];
}
auto it = std::minmax_element(arr.begin(), arr.end());
std::cout << "The max difference is " << *it.second - *it.first;
return 0;
}
Does it help?
#include <stdio.h>
#include <stdlib.h>
int maximum_difference(int arr[], int n)
{
//Init to same number
int max_num = arr[0];
int min_num = arr[0];
int difference;
//Find max and min by single traverse
for (int j = 1; j < n; j++)
{
if (max_num < arr[j])
{
max_num = arr[j];
}
if(min_num > arr[j])
{
min_num = arr[j];
}
}
/*
|----.--.--.--.--.--.--.--|
|..-3 -2 0 1 2 3 .. |
*/
if( max_num >= 0 && min_num >= 0) //both are +ve numbers
difference = max_num - min_num;
else if(max_num > 0 && min_num < 0) //max is positve and min is negative
difference = max_num + abs(min_num);
else //both are -negative
difference = abs(abs(max_num) - abs(min_num)); //abs value is the difference between max and min
return difference;
}
int main()
{
int n;
int arr[100];
printf("How many elements: ");
scanf("%d", &n);
//validate
if(n == 0 || n < 0)
printf("Enter valid number in 1..100");
if(n >100)
printf("The program can parse 100 elements at Maximum. Enter 1..100");
//read inputs
printf("\nEnter the integers: ");
for(int i=0; i<n; i++)
{
scanf("%d", &arr[i]);
}
//display difference
printf("\nMaximum difference is %d", maximum_difference(arr, n));
return 0;
}

How to convert 2D array to 1D in C++?

So for example I have a 2D array A={{1,2,3}, {2,3},{5}}; and I want to get all the rows existing in the array A. I have the length of array stored in variable "lenA", here lenA=3. Also I have an Array B which has the length of each subarray in A. Say B={3,2,1} in this case. In reference to my example array A, how to I dynamically get 3 subarrays from one 2D array i.e. A?
So as a result I would have something like:
A1={1,2,3}
A2={2,3}
A3={5}
You can't dynamically generate new identifiers in C++. The closest you can get is using the preprocessor to generate your names, and by definition, that's done before compilation.
If you already have a fixed number of named array pointers, you could assign those dynamically. But any solution that must accept an arbitrary number of rows at runtime will require that you use something like an array index.
for (int i = 0; i < lenA; i++)
{
// Do something with the row at A[i]
}
Pseudo code
for i in 0 to lenA-1
for j in 0 to lenB[i]-1
A[i][j] whatever...
My try converting A(4x4) to triangle *a[4]:
#include <iostream>
#include <algorithm>
int main()
{
constexpr int lenA = 4;
double A[lenA][lenA]={{1,2,3,4}, {5,6, 7, 0}, {8, 9,0,0},{10,0,0,0}};
double *a[lenA];
int B[lenA] = {4, 3, 2, 1};
for (int i=0; i < lenA; i++)
{
a[i] = new double [ B[i] ];
std::copy_n(A[i], B[i], a[i]);
}
for (int i=0; i<lenA; i++) {
std::cout << "row " << i << ": ";
for (int j=0; j<B[i]; j++) {
std::cout << a[i][j] << ". ";
}
std::cout <<std::endl;
}
return 0;
}
result:
$ ./a.exe
row 0: 1. 2. 3. 4.
row 1: 5. 6. 7.
row 2: 8. 9.
row 3: 10.
you can find the verification of the below code at http://cpp.sh/57pi2
A1D represent the 1-Dimensional array which you was looking for,
#include <iostream>
int main()
{
const int lenA = 4;
double A2D[][lenA]={{1,2,3,4},{5,6,7},{8,9},{10}};
double *A1D;
int B[lenA] = {4,3,2,1};
int num_of_elements = 0;
for (int i=0; i < lenA; i++)
num_of_elements += B[i];
A1D = new double[num_of_elements] ;
for (int i=0, k=0; i<lenA; i++)
for (int j=0; j<B[i]; j++)
A1D[k++] = A2D[i][j];
for (int j=0; j<num_of_elements; j++)
std::cout << A1D[j] << std::endl;
}
std::ranges in C++20 or ranges library (C++14 compliant) does it in clean way:
double A[][4] {
{ 1, 2, 3, 4},
{ 5, 6, 7, 0},
{ 8, 9, 0, 0},
{10, 0, 0, 0}
};
for (auto x : std::ranges::views::join(A))
std::cout << x << '\n';
https://godbolt.org/z/hPP7e9

Deleting an even number in an array and shift the elements

I'm trying to write a code where there is a research of even numbers and then it deletes the even numbers and then shifts all the other elements.
i is for offset and are the actual position of the elements in the array.
k is the position of the even number in the array.
int k;
for(i=0; i < N; i++)
{
if(Array[i] % 2 == 0)
{
for(k=i+1; k < N; k++)
{
Array[k-1] = Array[k];
}
N--;
}
}
Array=[2,10,3,5,8,7,3,3,7,10] the even numbers should be removed, but a 10
stays in the Array=[10,3,5,7,3,3,7].
Now is more than 3 hours that I'm trying to figure out what's wrong in my code.
This appears to be some sort of homework or school assignment. So what's the actual problem with the posted code?
It is that when you remove an even number at index i, you put the number that used to be at index i + 1 down into index i. Then you continue the outer loop iteration, which will check index i + 1, which is the number that was at the original i + 2 position in the array. So the number that started out at Array[i + 1], and is now in Array[i], is never checked.
A simple way to fix this is to decrement i when you decrement N.
Though already answered, I fail to see the reason people are driving this through a double for-loop, repetitively moving data over and over, with each reduction.
I completely concur with all the advice about using containers. Further, the algorithms solution doesn't require a container (you can use it on a native array), but containers still make it easier and cleaner. That said...
I described this algorithm in general-comment above. you don't need nested loops fr this. You need a read pointer and a write pointer. that's it.
#include <iostream>
size_t remove_even(int *arr, size_t n)
{
int *rptr = arr, *wptr = arr;
while (n-- > 0)
{
if (*rptr % 2 != 0)
*wptr++ = *rptr;
++rptr;
}
return (wptr - arr);
}
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
size_t n = remove_even(arr, sizeof arr / sizeof *arr);
for (size_t i=0; i<n; ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Output
3 5 7 3 3 7
If you think it doesn't make a difference, I invite you to fill an array with a million random integers, then try both solutions (the nested-for-loop approach vs. what you see above).
Using std::remove_if on a native array.
Provided only for clarity, the code above basically does what the standard algorithm std::remove_if does. All we need do is provide iterators (the array offsets and size will work nicely), and know how to interpret the results.
#include <iostream>
#include <algorithm>
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
auto it = std::remove_if(std::begin(arr), std::end(arr),
[](int x){ return x%2 == 0; });
for (size_t i=0; i<(it - arr); ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Same results.
The idiomatic solution in C++ would be to use a STL algorithm.
This example use a C-style array.
int Array[100] = {2,10,3,5,8,7,3,3,7,10};
int N = 10;
// our remove_if predicate
auto removeEvenExceptFirst10 = [first10 = true](int const& num) mutable {
if (num == 10 && first10) {
first10 = false;
return false;
}
return num % 2 == 0;
};
auto newN = std::remove_if(
std::begin(Array), std::begin(Array) + N,
removeEvenExceptFirst10
);
N = std::distance(std::begin(Array), newN);
Live demo
You could use a std::vector and the standard function std::erase_if + the vectors erase function to do this:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> Array = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
auto it = std::remove_if(
Array.begin(),
Array.end(),
[](int x) { return (x & 1) == 0 && x != 10; }
);
Array.erase(it, Array.end());
for(int x : Array) {
std::cout << x << "\n";
}
}
Output:
10
3
5
7
3
3
7
10
Edit: Doing it the hard way:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
for(size_t i = 0; i < N;) {
if((Array[i] & 1) == 0 && Array[i] != 10) {
for(size_t k = i + 1; k < N; ++k) {
Array[k - 1] = Array[k];
}
--N;
} else
++i; // only step i if you didn't shift the other values down
}
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}
Or simpler:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
size_t k = 0;
for(size_t i = 0; i < N; ++i) {
if((Array[i] & 1) || Array[i] == 10) {
// step k after having saved this value
Array[k++] = Array[i];
}
}
N = k;
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}

Algorithm for deleting multiple array elements and shifting array

I have an array let's say with 5 items, if element[i] is less than 3 need to move element[i+1] in place of element[i].
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
for (int i = 0; i < number; i++)
{
if (array[i] > number)
{
for (int j = 0; j < i - 1; j++)
{
array[j] = array[j + 1];
}
number = number - 1;
}
}
expected result is array = {2, 3, 1, anyNumber, anyNumber};
A O(n) working code for the above problem.. But as others pointed out in the comments.. You end up with an array that is using less space then allocated to it..
#include<stdio.h>
int main()
{
int arr[] = {4, 2, 3, 5, 1};
int* temp1 = arr;
int* temp2 = arr;
int i, n1 = 5, n2 = 5;
for(i = 0; i < n1; i++)
{
if(*temp2 >= 3)
{
*temp1 = *temp2;
temp1++;
temp2++;
}
else
{
n2--; //the number of elements left in the array is denoted by n2
temp2++;
}
}
}
Nested loops give you O(n2) complexity, and non-obvious code.
Better use std::remove_if:
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
remove_if( begin( array ), end( array ), [=]( int x ) { return x>number; } );
Disclaimer: code untouched by compiler's hands.
Try this code. You should not decrease number at each step. Also, the second loop should start at i and stop at the end of array:
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
for (int i = 0; i < number; i++)
{
if (array[i] > number)
{
for (int j = i; j < 5; j++)
{
array[j] = array[j + 1];
}
}
}
Here's a more compact and idiomatic (that's how I view it anyway) way to remove items from an array:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
int array[] = {4, 2, 3, 5, 1};
int* begin = array;
int* end = begin + sizeof(array)/sizeof(array[0]);
int number = 3;
end = std::remove_if(begin, end, [&number](int v) {return v > number;});
std::copy(begin, end, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
Just for comparison, here's a version using std::vector:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::vector<int> array = {4, 2, 3, 5, 1};
int number = 3;
auto end = std::remove_if(array.begin(), array.end(), [&number](int v) {return v > number;});
std::copy(array.begin(), end, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
As an alternative, if you want to keep your items, but denote what will be at some later time, "removed", the algorithm that can be used is stable_partition:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
int main()
{
int vValues[] = {4,2,3,5,1};
// partition the values on left and right. The left side will have values
// <= 3, and on right >3. The return value is the partition point.
int *p = std::stable_partition(vValues, vValues + 5,
std::bind2nd(std::less_equal<int>(), 3));
// display information
std::cout << "Partition is located at vValues[" << std::distance(vValues, p) << "]\n";
std::copy(vValues, vValues + 5, std::ostream_iterator<int>(std::cout, " "));
}
Output:
Partition is located at vValues[3]
2 3 1 4 5
You will see that 2,3,1 are on the left of partition p, and 4,5 are on the right of the partition p. So the "removed" items start at where p points to. The std::partition ensures the elements are still in their relative order when done.
I created my own example, hope this helps people as a reference:
// Removing an element from the array. Thus, shifting to the left.
void remove(){
int a[] = {1, 2, 3, 4, 5, 6};
int size = sizeof(a)/sizeof(int); // gives the size
for(int i = 0; i < size; i++){
cout << "Value: " << a[i] << endl;
}
int index = 2; // desired index to be removed
for(int i = 0; i < size; i++){
if(i == index){
for(int j = i; j < size; j++){
a[j] = a[j+1];
}
}
}
size--; // decrease the size of the array
cout << "\nTesting output: " << endl;
for(int i = 0; i < size; i++){
cout << "Value: " << a[i] << endl;
}
}
int main(){
remove();
return 0;
}

Linear Search returning array with indices value is found at

I attempted a program to return an array with the indicies of the array where a specific inputed value is found, but every run results in an error, which seems to be an infinite run time. The error seems to be occuring right after printing out the last of the indicies found.
Can anyone help?
(Side note: I've seen multiple pages about deleting pointers when done with them; should I be doing that here?)
Forgot to mention - I want the first slot of the returned array to save the size of the array, so that it can be accessed easily later on in the program
#include <iostream>
#include <vector>
using namespace std;
int* linearSearch(int* n, int k, int f) {
// Input: Index 0 Address ; Size of Array; Element to Search
// Output: Array of Found Indicies
vector <int> a;
int* b;
for(int i = 0; i < k; i++)
if(n[i] == f)
a.push_back(i);
*b = a.size();
for(int i = 0; i < a.size(); i++)
b[i + 1] = a[i];
return b;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
int* k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k[0]; i++) {
cout << "Found at index: " << k[i + 1] << endl;
}
return 0;
}
int* b;
....
*b = a.size();
b has to be allocated. Try following:
int* b = new int[a.size() + 1];
b[0] = a.size();
I see what you meant. b will have magically length in first element. This was in Pascal/Delphi but not the case in C/C++.
You are writing to heap memory that you never claimed.
int* b;
This pointer, having never been initialized, points to an undefined memory address. Then when you use the indexing operator to assign your matches, you are writing to the subsequent bytes following the undefined memory address.
You need to allocate space for storing the results using the 'new[]' operator. Additionally, if you had correctly claimed the memory, you would be assigning the number of match results to the first element in the result array - something that doesn't seem to be your intention.
Take a look at dynamic memory allocation in C++ using the new [] operator.
If you use std::vector anyway, why not to use it where it is needed the most? Also if you not suppose to modify array by that pointer express that by const pointer:
std::vector<int> linearSearch(const int* n, int k, int f)
{
std::vector<int> res;
for(int i = 0; i < k; i++)
if(n[i] == f) res.push_back(i);
return res;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k.size(); i++) {
cout << "Found at index: " << k[i] << endl;
}
return 0;
}
This is not perfect but this is much closer to a correct implementation and you should be able to take it further with some work:
#include <iostream>
#include <vector>
using namespace std;
std::vector<int> linearSearch(int* n, int k, int f)
{
vector <int> a;
for(int i = 0; i < k; i++)
{
if(n[i] == f)
{
a.push_back(i);
}
}
return a ;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> result = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(unsigned int i = 0; i < result.size(); i++)
{
cout << "Found at index: " << result[i + 1] << endl;
}
return 0;
}