Split an array at a specific value C++ - c++

Say I have an array like this:
int arr [9] = {2,1,5,8,9,4,10,15,20}
How can you split the array at a certain value threshold? So say int 8 is our splitting value, the end result would be two separate arrays (or a 2d array if you want to give that a shot) that in this example would be arr1 [4] = {1,2,4,5} and arr2 [5] = {8,9,10,15,20}. arr1 stores all the values in arr that are below 8 and and arr2 stores all the values in arr that are 8 and above.
I haven't been able to locate sufficient documentation or examples of this being done and I think array manipulation and splitting is worth having examples of.

Use std::partition, or if you want to maintain the relative order and not sort the data, std::stable_partition.
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
int pivot = 8;
int arr [9] = {2,1,5,8,9,4,10,15,20};
// get partition point
int *pt = std::stable_partition(arr, std::end(arr), [&](int n) {return n < pivot;});
// create two vectors consisting of left and right hand side
// of partition
std::vector<int> a1(arr, pt);
std::vector<int> a2(pt, std::end(arr));
// output results
for (auto& i : a1)
std::cout << i << " ";
std::cout << '\n';
for (auto& i : a2)
std::cout << i << " ";
}
Live Example

If you can use C++11 then this is one way of using the standard library:
Using a partition_point: (edited the example from the link)
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
std::array<int, 9> v = {2,1,5,8,9,4,10,15,20};
auto is_lower_than_8 = [](int i){ return i < 8; };
std::partition(v.begin(), v.end(), is_lower_than_8 );
auto p = std::partition_point(v.begin(), v.end(), is_lower_than_8 );
std::cout << "Before partition:\n ";
std::vector<int> p1(v.begin(), p);
std::sort(p1.begin(), p1.end());
std::copy(p1.begin(), p1.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\nAfter partition:\n ";
std::vector<int> p2(p, v.end());
std::sort(p2.begin(), p2.end());
std::copy(p2.begin(), p2.end(), std::ostream_iterator<int>(std::cout, " "));
}
Which prints:
Before partition:
1 2 4 5
After partition:
8 9 10 15 20

I'm working on a solution with loops. This is a work in progress. Let me know what you think.
void splitarr(int arr[], int length) {
int accu = 0;
int accu2 = 0;
int splitter = rand() % 20;
for (int i = 0; i < length; i++) {
if (i != splitter) {
accu++;
}
}
int arr1[accu];
for (int i = 0; i < length; i++) {
if (i != splitter) {
arr1[i] = i;
}
}
for (int i = 0; i < length; i++) {
if (i == splitter) {
accu2++;
}
}
int arr2[accu2];
for (int i = 0; i < length; i++) {
if (i == splitter) {
arr2[i] = i;
}
}
}

Related

How to shift values of given array by moving first value to the last C++

I was struggling on how to move the first value to the las in order like shown in the picture
enter image description here
What should I do?
#include <iostream>
using namespace std;
void rotate(int A[], int n = 5)
{
int x = A[n - 1], i;
for (i = n - 1; i > 0; i--)
{
A[i] = A[i -1];
}
A[0] = x;
}
int main()
{
int A[] = { 1, 2, 3, 4, 5 }, i;
int n = sizeof(A) / sizeof(A[5]);
cout << "Given array is \n";
for (i = 0; i < n; i++)
cout << A[i] << ' ';
for (int j = 0; j < n; j++)
{
rotate(A, n);
cout << "\nStep " << j << " --> ";
for (i = 0; i < n; i++)
{
cout << A[i] << ' ';
}
}
return 0;
}
Your code is still quite "C" like. Here is an example that hopefully will teach you some C++ coding :
#include <algorithm>
#include <iostream>
#include <vector>
// passing arrays is easier using std::vector/std::array (no need to pass size seperately)
void rotate(std::vector<int>& values)
{
// using algorithm's std::swap you can better show WHAT you are doing
// vector and array also have a size() method so you don't
// have to use "C" style sizeof tricks.
for (std::size_t n = 0; n < values.size() - 1; ++n)
{
std::swap(values[n], values[n + 1]);
}
}
int main()
{
// prefer std::vector (or std::array) in C++. Not "C" style arrays
std::vector<int> values{ 1,2,3,4,5 };
rotate(values);
// use range based for loop if you can.
for (const auto value : values)
{
std::cout << value << " ";
}
return 0;
}

Getting random numbers on vector operation c++

I'm getting weird numbers as output in this code :
#include <iostream>
#include <vector>
int main(){
std::vector<std::vector<int>> vec = {{0,1},{2,3}};
vec.push_back({4,5});
vec.push_back({5,6});
for (int i = 0; i < vec.size(); i++){
for (int i2 = 0; i2 < vec.size(); i2++){
std::cout << vec[i][i2] << std::endl;
}
}
return 0;
}
It's returning to me:
0
1
1280136264
0
2
3
347673833
38962
4
5
297276653
134256690
5
6
280499436
268474418
I just want to know how to do it properly, and why I'm getting these numbers.
The output you are seeing is due to undefined behavior in your code.
The outer vector object has 4 inner vector<int> objects added to it. Each of those inner vector<int> objects is holding 2 int values.
Your inner for loop is going out of bounds of the inner vector<int> objects, by trying to access 4 int values when there are only 2 int values available.
In your inner for loop, you need to change vec.size() to vec[i].size() instead, eg:
#include <iostream>
#include <vector>
int main(){
std::vector<std::vector<int>> vec = {{0,1},{2,3}};
vec.push_back({4,5});
vec.push_back({5,6});
for (size_t i = 0; i < vec.size(); ++i){
for (size_t i2 = 0; i2 < vec[i].size(); ++i2){
std::cout << vec[i][i2] << std::endl;
}
/* alternatively:
auto &vec2 = vec[i];
for (size_t i2 = 0; i2 < vec2.size(); ++i2){
std::cout << vec2[i2] << std::endl;
}
*/
}
return 0;
}
Online Demo
That being said, a safer way to code this is to use range-for loops instead, eg:
#include <iostream>
#include <vector>
int main(){
std::vector<std::vector<int>> vec = {{0,1},{2,3}};
vec.push_back({4,5});
vec.push_back({5,6});
for (auto &vec2 : vec){
for (auto value : vec2){
std::cout << value << std::endl;
}
}
return 0;
}
Online Demo

Find the missing numbers in the given array

Implement a function which takes an array of numbers from 1 to 10 and returns the numbers from 1 to 10 which are missing. examples input: [5,2,6] output: [1,3,4,7,8,9,10]
C++ program for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Function to find the missing elements
void printMissingElements(int arr[], int N)
{
// Initialize diff
int diff = arr[0] - 0;
for (int i = 0; i < N; i++) {
// Check if diff and arr[i]-i
// both are equal or not
if (arr[i] - i != diff) {
// Loop for consecutive
// missing elements
while (diff < arr[i] - i) {
cout << i + diff << " ";
diff++;
}
}
}
}
Driver Code
int main()
{
// Given array arr[]
int arr[] = { 5,2,6 };
int N = sizeof(arr) / sizeof(int);
// Function Call
printMissingElements(arr, N);
return 0;
}
How to solve this question for the given input?
First of all "plzz" is not an English world. Second, the question is already there, no need to keep writing in comments "if anyone knows try to help me".
Then learn standard headers: Why should I not #include <bits/stdc++.h>?
Then learn Why is "using namespace std;" considered bad practice?
Then read the text of the problem: "Implement a function which takes an array of numbers from 1 to 10 and returns the numbers from 1 to 10 which are missing. examples input: [5,2,6] output: [1,3,4,7,8,9,10]"
You need to "return the numbers from 1 to 10 which are missing."
I suggest that you really use C++ and get std::vector into your toolbox. Then you can leverage algorithms and std::find is ready for you.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
std::vector<int> missingElements(const std::vector<int> v)
{
std::vector<int> missing;
for (int i = 1; i <= 10; ++i) {
if (find(v.begin(), v.end(), i) == v.end()) {
missing.push_back(i);
}
}
return missing;
}
int main()
{
std::vector<int> arr = { 5, 2, 6 };
std::vector<int> m = missingElements(arr);
copy(m.begin(), m.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
return 0;
}
If you want to do something with lower computational complexity you can have an already filled vector and then mark for removal the elements found. Then it's a good chance to learn the erase–remove idiom:
std::vector<int> missingElements(const std::vector<int> v)
{
std::vector<int> m = { -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (const auto& x: v) {
m[x] = -1;
}
m.erase(remove(m.begin(), m.end(), -1), m.end());
return m;
}
By this approach we are using space to reduce execution time. Here the time complexity is O(N) where N is the no of elements given in the array and space complexity is O(1) i.e 10' .
#include<iostream>
void printMissingElements(int arr[], int n){
// Using 1D dp to solve this
int dp[11] = {0};
for(int i = 0; i < n; i++){
dp[arr[i]] = 1;
}
// Traverse through dp list and check for
// non set indexes
for(int i = 1; i <= 10; i++){
if (dp[i] != 1) std::cout << i << " ";
}
}
int main() {
int arr[] = {5,2,6};
int n = sizeof(arr) / sizeof(int);
printMissingElements(arr, n);
}
void printMissingElements(int arr[], int n,int low, int high)
{
bool range[high - low + 1] = { false };
for (int i = 0; i < n; i++) {
if (low <= arr[i] && arr[i] <= high)
range[arr[i] - low] = true;
}
for (int x = 0; x <= high - low; x++) {
if (range[x] == false)
std:: cout << low + x << " ";
}
}
int main()
{
int arr[] = { 5,2,6,6,6,6,8,10 };
int n = sizeof(arr) / sizeof(arr[0]);
int low = 1, high = 10;
printMissingElements(arr, n, low, high);
return 0;
}
I think this will work:
vector<int> missingnumbers(vector<int> A, int N)
{ vector<int> v;
for(int i=1;i<=10;i++)
v.push_back(i);
sort(A.begin(),A.end());
int j=0;
while(j<v.size()) {
if(binary_search(A.begin(),A.end(),v[j]))
v.erase(v.begin()+j);
else
j++;
}
return v;
}

why can't I store values in my 2D vector by push back?

I got stuck in many problems where I was trying to store values in 2D vectors.
So I have written this simple code.
I am just storing and printing my values :
int main()
{
vector<vector<int>> vec;
vector<int> row{1,3,5,7,9,12,34,56};
int i,n,m,rs,vs;
rs=row.size();
cout<<"rs = "<<rs<<endl;
for(i=0;i<(rs/2);i++)
{
vec[i].push_back(row.at(i));
vec[i].push_back(row.at(i+4));
}
vs=vec.size();
cout<<vs<<endl;
for(n=0;n<vs;n++)
{
for(m=0;m<2;m++)
{
cout<<vec[n][m]<<" ";
}
cout<<endl;
}
return 0;
}
First you should read Why is “using namespace std;” considered bad practice?.
Declare variables when you use them and not at the beginning of your program.
The vector vec is empty at the beginning. In the loop
for(i=0;i<(rs/2);i++)
{
vec[i].push_back(row.at(i));
vec[i].push_back(row.at(i+4));
}
you are taking a reference to the i-th element in vec with
vec[i]
but this element does not exist. This is undefined behavior and can result in a segmentation fault. You can fix it by constructing the vector with the needed elements
#include <iostream>
#include <vector>
int main()
{
std::vector<int> row{1,3,5,7,9,12,34,56};
int rs = row.size();
std::vector<std::vector<int>> vec(rs / 2);
std::cout << "rs = " << rs << '\n';
for(int i = 0; i < rs / 2; ++i)
{
vec[i].push_back(row.at(i));
vec[i].push_back(row.at(i + 4));
}
int vs = vec.size();
std::cout << vs << '\n';
for(int n = 0; n < vs; ++n)
{
for(int m = 0; m < 2; ++m)
{
std::cout << vec[n][m] << " ";
}
std::cout << '\n';
}
return 0;
}
In this example the line
std::vector<std::vector<int>> vec(rs / 2);
constructs a vector containing rs / 2 default constructed elements. Alternatively you can start with an empty vector and push back elements in the loop
#include <iostream>
#include <vector>
int main()
{
std::vector<int> row{1,3,5,7,9,12,34,56};
int rs=row.size();
std::vector<std::vector<int>> vec;
std::cout << "rs = " << rs << '\n';
for(int i = 0; i < rs / 2; ++i)
{
vec.push_back({row.at(i), row.at(i+4)});
//
// is similar to:
// vec.push_back({});
// vec.back().push_back(row.at(i));
// vec.back().push_back(row.at(i+4));
//
// is similar to:
// vec.push_back({});
// vec[i].push_back(row.at(i));
// vec[i].push_back(row.at(i+4));
}
int vs = vec.size();
std::cout << vs << '\n';
for(int n = 0; n < vs; ++n)
{
for(int m = 0; m < 2; ++m)
{
std::cout << vec[n][m] << " ";
}
std::cout << '\n';
}
return 0;
}
I recommend the first solution. It's better to allocate memory for all elements and work with it instead of allocate memory in each loop iteration.

Finding the size of an array

The idea of the program is to input elements in an array. Then give the integer 'x' a value. If 'x' is 3 and the array a[] holds the elements {1,2,3,4,5,6}, we must "split" a[] into two other arrays. Lets say b[] and c[].
In b[] we must put all values lower or equal to 3 and in c[] all values greater than 3.
My question is- How can i express the 3 elements in b[i]?
#include <iostream>
using namespace std;
int main()
{
int a[6];
int b[6];
int c[6];
int d;
for (int i = 0; i < 6; i++) {
cin >> a[i];
}
cin >> d;
for (int i = 0; i < 6; i++) {
if (d >= a[i]) {
b[i] = a[i]; // if d is 3, then i have 3 elements. How can i express them?
}
}
for (int i = 0; i < 6; i++) {
if (d< a[i]) {
c[i] = a[i];
}
}
for (int i = 0; i < 3; i++) {
cout << b[i];
}
cout << endl;
for (int i = 3; i < 6; i++) {
cout << c[i];
}
return 0;
}
I think all you're trying to do is have a way to determine how many int values you're copying from a[] to either b[] or c[]. To do that, introduce two more counters that start at zero and increment with each item copied to the associated array:
Something like this:
#include <iostream>
using namespace std;
int main()
{
int a[6];
int b[6], b_count=0; // see here
int c[6], c_count=0; // see here
int d;
for (int i = 0; i < 6; i++) {
cin >> a[i];
}
cin >> d;
for (int i = 0; i < 6; i++) {
if (d >= a[i]) {
b[b_count++] = a[i]; // see here
}
}
for (int i = 0; i < 6; i++) {
if (d< a[i]) {
c[c_count++] = a[i]; // see here
}
}
for (int i = 0; i < b_count; i++) { // see here
cout << b[i];
}
cout << endl;
for (int i = 3; i < c_count; i++) { // and finally here
cout << c[i];
}
return 0;
}
Now, if you want b[] or c[] to be dynamic in their space allocation, then dynamic-managed containers like st::vector<> would be useful, but I don't think that is required for this specific task. Your b[] and c[] are already large enough to hold all elements from a[] if needed.
WhozCraigs answer does a good job showing what you need to solve this using traditional arrays according to your tasks requirements.
I'd just like to show you how this can be done if you were allowed the full arsenal of the standard library. It is why people are calling for you to use std::vector. Things gets simpler that way.
#include <algorithm>
#include <iostream>
int main()
{
int a[6] = {1, 2, 3, 4, 5, 6 }; // Not using input for brevity.
int x = 3; // No input, for brevity
// Lets use the std:: instead of primitives
auto first_part = std::begin(a);
auto last = std::end(a);
auto comparison = [x](int e){ return e <= x; };
auto second_part = std::partition(first_part, last, comparison);
// Print the second part.
std::for_each(second_part, last, [](int e){ std::cout << e; });
// The first part is first_part -> second_part
}
The partition function does exactly what your problem is asking you to solve, but it does it inside of the array a. The returned value is the first element in the second part.
use std::vectors. do not use int[]s.
with int[]s (that are pre-c++11) you could, with a few heavy assumptions, find array length with sizeof(X)/sizeof(X[0]); This has, however, never been a good practice.
in the example you provided, probably you wanted to:
#define MAX_LEN 100
...
int main() {
int a[MAX_LEN];
int b[MAX_LEN];
int c[MAX_LEN];
int n;
std::cout << "how many elements do you want to read?" << std::endl;
std::cin >> n;
and use n from there on (these are common practice in programming schools)
Consider a function that reads a vector of ints:
std::vector<int> readVector() {
int n;
std::cout << "how many elements do you want to read?" << std::endl;
std::cin >> n;
std::vector<int> ret;
for (int i=0; i<n; i++) {
std::cout << "please enter element " << (i+1) << std::endl;
int el;
std::cin >> el;
ret.push_back(el);
}
return ret;
}
you could use, in main, auto a = readVector(); auto b = readVector(); a.size() would be the length, and would allow to keep any number of ints
Here's an example of how you'll approach it once you've a little more experience.
Anything you don't understand in here is worth studying here:
#include <iostream>
#include <vector>
#include <utility>
std::vector<int> get_inputs(std::istream& is)
{
std::vector<int> result;
int i;
while(result.size() < 6 && is >> i) {
result.push_back(i);
}
return result;
}
std::pair<std::vector<int>, std::vector<int>>
split_vector(const std::vector<int>& src, int target)
{
auto it = std::find(src.begin(), src.end(), target);
if (it != src.end()) {
std::advance(it, 1);
}
return std::make_pair(std::vector<int>(src.begin(), it),
std::vector<int>(it, src.end()));
}
void print_vector(const std::vector<int>& vec)
{
auto sep = " ";
std::cout << "[";
for (auto i : vec) {
std::cout << sep << i;
sep = ", ";
}
std::cout << " ]" << std::endl;
}
int main()
{
auto initial_vector = get_inputs(std::cin);
int pivot;
if(std::cin >> pivot)
{
auto results = split_vector(initial_vector, pivot);
print_vector(results.first);
print_vector(results.second);
}
else
{
std::cerr << "not enough data";
return 1;
}
return 0;
}
example input:
1 2 3 4 5 6
3
expected output:
[ 1, 2, 3 ]
[ 4, 5, 6 ]