I am trying to sort a vector using sort so that all the even numbers and odd numbers are brought together but somehow that doesnt seem to work.
Sample code below.
#include <iostream>
#include <algorithm>
#include <vector>
bool myfunction (int i,int j) { return ((i&2)>(j&2)); }
bool yourfunction (int i,int j) { return (i<j); }
int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> myvector (myints, myints+8);
int count=0;
// using function as comp
std::sort (myvector.begin(), myvector.end(), myfunction);
for (std::vector<int>::iterator it=myvector.begin();it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
{
if(((*it)&2)==0)
{
break;
}
count++;
}
std::cout << "myvector contains after 1st sort:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::sort (myvector.begin()+count, myvector.end(), yourfunction);
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
You can use the function std::partition to do this.
auto oddStart = std::partition(std::begin(myints),
std::end(myints),
[](int i){ return i % 2 == 0; });
After this your even values are from
for(auto it = std::begin(myints); it != oddStart; ++it)
and the odds are
for(auto it = oddStart; it != std::end(myints); ++it)
If you want to stick to using std::sort you can use this function:
bool myfunction (int i,int j) { return ((i % 2) > (j % 2)); }
Running sort with your input results in:
71
45
53
33 //ODD
32 //EVEN
12
26
80
Related
I create and modify a simple list. I replace the element at index 1 of the list. How would I semantically accomplish the same thing with a while loop. The tutorial instructor remarked that the current code is quite ugly and a while loop would accomplish the same thing in a much more simple and pretty fashion. I can't figure it out.
#include <iostream>
#include <list>
int main() {
std::list<int> numbers;
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
numbers.push_front(0);
std::list<int>::iterator it = numbers.begin();
it++;
numbers.insert(it, 100);
std::cout << "Current element is: " << *it << '\n';
std::list<int>::iterator eraseIt = numbers.begin();
eraseIt++;
eraseIt = numbers.erase(eraseIt);
std::cout << "erasing at element: " << *eraseIt << '\n';
for (std::list<int>::iterator it = numbers.begin(); it != numbers.end();) {
if (*it == 2) {
numbers.insert(it, 1234);
}
if (*it == 1) {
it = numbers.erase(it);
} else {
it++;
}
}
for (std::list<int>::iterator it = numbers.begin(); it != numbers.end();
it++) {
std::cout << *it << '\n';
}
return 0;
}
You can probably do this if iterators are required:
// ...
std::list<int>::iterator it = ++numbers.begin();
numbers.insert(it, 100);
std::cout << "Current element is: " << *it << '\n';
std::list<int>::iterator eraseIt = ++numbers.begin();
eraseIt = numbers.erase(eraseIt);
std::cout << "erasing at element: " << *eraseIt << '\n';
it = numbers.begin();
while (it != numbers.end())
{
if (*it == 2) {
numbers.insert(it, 1234);
}
if (*it == 1) {
it = numbers.erase(it);
}
else {
++it;
}
}
for (auto& i : numbers)
{
std::cout << i << std::endl;
}
// ...
I have below two pieces of code:
// multiset::begin/end
#include <iostream>
#include <set>
#include <vector>
int main ()
{
int myints[] = {42,71,12};
std::set<int> mymultiset (myints,myints+2);
std::set<int> mymultiset1 (myints,myints+2);
std::set<int>::iterator it=std::prev(mymultiset.end());
std::set<int>::iterator it1=std::prev(mymultiset1.end());
std::cout << "mymultiset contains:";
for (; it!=std::prev(mymultiset.begin()) && it1!=std::prev(mymultiset1.begin()); --it,--it1)
std::cout << "PPP" << *it;
std::cout << "\nmymultiset contains:";
for (it=std::prev(mymultiset.end()); it!=std::prev(mymultiset.begin()) ; --it)
std::cout << "UUU" << *it;
std::cout << "\nmymultiset contains:";
for ( it=mymultiset.begin(); it!=(mymultiset.end()); it++)
std::cout << "KKK" << *it;
std::cout << '\n';
return 0;
}
but why the output is
mymultiset contains:PPP71
mymultiset contains:UUU71
mymultiset contains:KKK42KKK71
1) I'm not sure, but there's probably UB and it can cause segmentation fault (for example when you use clang) :
std::prev(container.begin())
For GCC, std::prev(container.begin() and container.begin() return the same value.
2) Why didn't you use reverse_iterator?
for (auto it = mymultiset.rbegin(); it != mymultiset.rend(); ++it)
std::cout << "PPP" << *it;
or
for (auto it: boost::adaptors::reverse(mymultiset))
std::cout << "PPP" << it;
#include <iostream>
#include <unordered_set>
using namespace std;
void arraySet(unordered_set<int> n[]){
for(auto it1 = n->begin(); it1!= n->end(); it1++){
cout << "n[" <<*it1<<"]: ";
// for(auto it = it1->begin(); it!= it1->end(); it++){
// cout << *it <<" ";
// }
cout << endl;
}
}
int main()
{
unordered_set<int> n[3];
n[0].insert(734);
n[0].insert(23);
n[0].insert(634);
n[1].insert(2);
n[1].insert(1);
n[2].insert(1);
arraySet(n);
return 0;
}
Can anyone help me explain how to iterator through this set inside array. I believe an easy way is to convert it to set inside vector.
Size of the array needs to be passed as well to the function for you to be able to iterate through all the sets of the array. With just passing the pointer, size cannot be determined and dereferencing n->begin will iterate through only the first set.
void arraySet(unordered_set<int> n[], int size) {
for (auto i = 0; i < size; i++) {
for (auto it1 = n[i].begin(); it1 != n[i].end(); it1++) {
cout << "n[" << *it1 << "]: ";
// for(auto it = it1->begin(); it!= it1->end(); it++){
// cout << *it <<" ";
// }
cout << endl;
}
}
}
int main()
{
unordered_set<int> n[3];
n[0].insert(734);
n[0].insert(23);
n[0].insert(634);
n[1].insert(2);
n[1].insert(1);
n[2].insert(1);
arraySet(n,3);
return 0;
}
Or you could use std::vector to contain the sets and pass it instead.
std::vector<unordered_set<int>> n(3); // Sets the size to 3 elements
The function definition would be changed to
void arraySet(std::vector<unordered_set<int>>& n) {
for (size_t i = 0; i < n.size(); i++) {
for (auto it1 = n[i].begin(); it1 != n[i].end(); it1++) {
cout << "n[" << *it1 << "]: ";
// for(auto it = it1->begin(); it!= it1->end(); it++){
// cout << *it <<" ";
// }
cout << endl;
}
}
}
I want to print only first 10 inserted items while leaving the rest behind. What code do i have to use (instead of using myset.end() ) to print only first 10 integers instead of printing every single integer.
int main ()
{
std::set<int> myset;
std::set<int>::iterator it;
// set some initial values:
for (int i=1; i<=20; ++i)
myset.insert(i*10);
std::cout << "myset contains:";
for (it=myset.begin(); it!=myset.end(); ++it)
std::cout << *it << ' ';
std::cout << "\n\n";
return 0;
}
You might use std::next as follow:
const auto begin = myset.begin();
const auto end = myset.size() < 10 ? myset.end() : std::next(begin, 10);
for (auto it = begin; it != end; ++it) {
std::cout << *it << ' ';
}
You can just keep a count variable and break the loop as soon as it reaches 10 or you reach myset.end().
int main ()
{
std::set<int> myset;
std::set<int>::iterator it;
// set some initial values:
for (int i=1; i<=20; ++i)
myset.insert(i*10);
int count = 0;
std::cout << "myset contains:";
for (it=myset.begin(); count < 10 && it!=myset.end(); ++it, ++count)
std::cout << *it << ' ';
std::cout << "\n\n";
return 0;
}
I would do it like this:
int nCount = 0;
for (it=myset.begin(); nCount<10 && it!=myset.end(); ++nCount, ++it)
{
std::cout << *it << ' ';
}
Hope this helps.
I am making some testing of vectors arrays and I don't know how to print it.
Here is my code:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include "vector"
#include <windows.h>
using namespace std;
vector<vector<int>> generateArrays(){
vector<vector<int>> cisla;
for(unsigned int i=1; i < 11; i++){
vector<int> pole;
vector<int> pole2;
for(unsigned int j=0; j < i*5; j++){
int a = rand();
pole.push_back(a);
pole2.push_back(a);
}
cisla.push_back(pole);
cisla.push_back(pole2);
}
return cisla;
}
vector<vector<int>> arrays = generateArrays();
void Print (const vector<int>& arrays){
// function for prinitng arrays
}
int main(){
Print(arrays);
system("pause");
}
What I need is some function to write down all numbers in vector arrays. I tried to Google it but none of the code work for me.
// requires #include <algorithm> for std::copy
// requires #include <iterator> for std::ostream_iterator
void Print(const vector<vector<int>>& arrays, std::ostream& out = std::cout)
{
for(const auto& array:arrays) {
std::copy(array.begin(), array.end(), std::ostream_iterator<int>(out, " "));
out << std::endl;
}
}
You can use vector::iterator, for instance:
vector<vector<int>>::iterator i = arrays.begin();
vector<int>::iterator j = *i.begin();
for(;i != arrays.end(); ++i) {
for(;j != *i.end(); ++j) {
std::cout << *j << " ";
}
std::cout << "\n";
}
void Print (const vector<int>& arrays){
for (std::vector<int>::iterator it = arrays.begin() ;
it != arrays.end();
++it)
std::cout << ' ' << *it;
}
#include <algorithm>
vector<vector<int>>::iterator it = arrays.begin();
while ( !(it == arrays.end()) {
std::copy( (*it).begin(), (*it).end(),
std::ostream_iterator<int>( std::cout, ","));
++it;
}
As you have std::vector<std::vector<int>> then the function could look as
void Print( const std::vector<std::vector<int>> &arrays )
{
for ( const std::vector<int> &v : arrays )
{
for ( int x : v ) std::cout << x << ' '; // you can include std::setw here
std::cout << std::endl;
}
}
Or if you need to output only std::vector<int> then it will look as
void Print( const std::vector<int> &arrays )
{
for ( int x : arrays ) std::cout << x << ' '; // you can include std::setw here
}
If your compiler does not support the range based for statement then you can use for example standard algorithm std::copy.
void Print( const std::vector<int> &arrays )
{
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, " " ) );
}
Or you can use an ordinary loop
void Print( const std::vector<int> &arrays )
{
for ( std::vector<int>::size_type i = 0; i < arrays.size(); i++ )
{
std::cout << arrays[i] << ' '; // you can include std::setw here
}
}
Or with iterators
void Print( const std::vector<int> &arrays )
{
for ( auto it = arrays.begin(); it != arrays.end(); ++it )
{
std::cout << *it << ' '; // you can include std::setw here
}
}
What about this?
Create a stream output operator for vector of T like this:
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> const & array)
bool seenFirst = false;
os << "[ ";
for (auto const & i : array)
{
if (!seenFirst)
{
seenFirst = true;
os << i;
}
else
{
os << ", " << i;
}
}
os << "]";
return os;
}
At the end you might use it for std::vector<int> as well as for std::vector< std::vector <int> > like this:
std::cout << arrays;
If you have Print prototype as shown
then,
void Print (const vector<int>& arrays){
for(auto x:arrays)
std::cout << x <<" ";
}
int main(){
for(const auto& array:arrays)
Print(array);
system("pause");
}
Otherwise you can combine both in one function like
void Print (const vector<vector<int>>& arrays){
for(const auto& array:arrays)
for(auto x:array)
std::cout << x <<" ";
}
In C++11``
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';