use of iterators from the middle of the loop - c++

i have a vector of vector "mydata". i want to iterate my data in negative direction. the iterator should be started from the middle to the beginning.
i wish to use following way;
vector<vector<int> >::const_iterator points;
int i, k;
(lets assume k = 10)
for (i=k, points=mydata.begin()+k; i != -1; i--, points--){
//do stuff
}
does this way is the proper way to iterate in backward? (I am using dev c++, so predicates and some modern commands cant be used.)
Hope your suggestions to do this.

A possible solution using reverse_iterators vector::rbegin() and vector::rend():
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
for (std::vector<int>::const_reverse_iterator it = v.rbegin()+(v.size()/2);
it != v.rend();
it++)
{
std::cout << *it << "\n";
}
return 0;
}

You can use std::vector::const_reverse_iterator. Here's the example of how to iterate backwards through the vector, starting from the middle:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
for(int i = 0; i< 10; i++)
v.push_back(i);
std::vector<int>::const_reverse_iterator it = v.rbegin() + 5;
for(;it != v.rend(); it++)
{
std::cout << *it << std::endl;
}
return 0;
}
Output:
4
3
2
1
0

Since it's vector, you dont need to use iterator at all:
for (int k = 4; k >= 0; k--)
{
// do something with v[k]
}
Example:
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char** argv)
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
vector<int> v(arr, arr + 10);
for (int k = 4; k >= 0; k--)
{
cout << v[k] << endl;
}
}
output:
5
4
3
2
1

There are roughly two nice solutions. Either you just write the loop:
vector<int>::const_iterator i = v.begin() + 4;
do {
// stuff with *i
while (--i != v.begin());
or use reverse iterators and the standard STL algorithms:
std::for_each(v.rend()-4, v.rend(), &stuff);

Related

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;
}

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";
}
}

reduce the complexity of the program

Here is the program to find the pairs that sums up to 3.
For example:
INPUT : 0,3,5,1,2,4
OUTPUT: 0,3,1,2.
That means it should return all the pairs whose sum is equal to 3.
But I want to reduce the time complexity of this program. Right now I am using two nested for loops.
Can anyone suggest a better method to reduce the time complexity.
#include<iostream>
#include <vector>
using namespace std;
void main()
{
vector<int> v;
vector<int> r;
int x;
cout << "Enter the elements";
for(int i = 0; i < 6; i++)
{
cin >> x;
v.push_back(x);
}
for(int i = 0 ; i < v.size() - 1; i++)
{
for(int j = i + 1; j < v.size(); j++)
{
if(v[i] + v[j] == 3)
{
r.push_back(v[i]);
r.push_back(v[j]);
}
}
}
cout << "\noutput\n";
for(int i = 0 ; i < r.size(); i++)
{
cout<<r[i]<<"\n";
}
}
I'd do two preparation steps; First, eliminate all numbers > 3, as they will not be part of any valid pair. This reduces the complexity of the second step. Second, sort the remaining numbers such that a single walk through can then find all the results.
The walk through approaches the pairs from both ends of the sorted array; if a pair is found, both bounds can be narrowed down; if the current endings do sum up to a value > 3, only one boundary is narrowed.
Runtime complexity is O(N logN), where N is the count of elements <= 3; O(N logN) basically comes from sorting; the two single walk throughs will not count for large Ns.
int main(int argc, char* argv[]) {
const int N = 3;
std::vector<int> input{ 0,3,5,1,2,4};
std::vector<int>v(input.size());
int t=0;
for (auto i : input) {
if (i <= N) {
v[t++]=i;
}
}
std::sort (v.begin(), v.end());
long minIdx = 0;
long maxIdx = v.size()-1;
while (minIdx < maxIdx) {
int minv = v[minIdx];
int maxv = v[maxIdx];
if (minv+maxv == 3) {
cout << minv << '+' << maxv << endl;
minIdx++;maxIdx--;
}
else
minIdx++;
}
return 0;
}
You are searching for all the combinations between two numbers in n elements, more specifically, those that sum up to specific value. Which is a variation of the subset sum problem.
To make this happen you could generate all combinations without repetitions of the indexes of the vector holding the values. Here is an example of how to do this recursively and here is an example of how to do it iteratively, just to get an idea and possibly use it as a benchmark in your case.
Another approaches are dynamic programming and backtracking.
Late answer but works for negative integers too... For first, find the smallest number in the std::vector<int>, then like this answer says, remove all elements (or copy the opposite), which are higher than 3 + minimum. After sorting this std::vector<int> iterate through it from both ends with condition shown bellow:
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
std::vector<int> findPairs(const std::vector<int>& input, const int sum) {
int minElem = INT_MAX;
for(auto lhs = input.begin(), rhs = input.end() - 1; lhs < rhs;
++lhs, --rhs) {
const int elem = (*lhs < *rhs ? *lhs : *rhs);
if(elem < minElem)
minElem = elem;
}
std::vector<int> temp(input.size());
const auto tempBegin = temp.begin();
const auto tempEnd = std::remove_copy_if(input.begin(), input.end(),
temp.begin(), [minElem, sum](int elem) {
return (elem + minElem) > sum;
});
std::sort(tempBegin, tempEnd);
std::vector<int> result;
auto leftIter = tempBegin;
auto rightIter = tempEnd - 1;
while(leftIter < rightIter) {
if(*leftIter + *rightIter == sum) {
result.push_back(*leftIter++);
result.push_back(*rightIter--);
}
else {
if(sum - *leftIter < *rightIter) rightIter--;
else leftIter++;
}
}
return result;
}
int main() {
auto pairs = findPairs({ 0, 3, 5, 1, 2, 4, 7, 0, 3, 2, -2, -4, -3 }, 3);
std::cout << "Pairs: { ";
for(auto it = pairs.begin(); it != pairs.end(); ++it)
std::cout << (it == pairs.begin() ? "" : ", ") << *it;
std::cout << " }" << std::endl;
}
The code above will results the following:
Pairs: { -4, 7, -2, 5, 0, 3, 0, 3, 1, 2 }
I think you can solve this in O(n) with a map.
public void printPairs(int[] a, int v)
{
map<int, int> counts = new map<int, int>();
for(int i = 0; i < a.length; i++)
{
if(map.count(a[i]) == 0)
{
map[a[i]] = 1;
}
else
{
map[a[i]] = map[a[i]] + 1;
}
}
map<int, int>::iterator it = map.begin();
while(it != map.end())
{
int v1 = it->second;
if (map.count(v - v1) > 0)
{
// Found pair v, v1
//will be found twice (once for v and once for v1)
}
}
}

Split an array at a specific value 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;
}
}
}