vector array function question

Oct 16, 2014 at 1:45am
came back with other question about vector array function I am writing. I need some hints on how to return the number next to the interesting number I am looking for??

cull's job is to call your interesting function to create and return an array
that consists of all the interesting elements of v together will all the
elements of v that are next to interesting numbers.
For example, if your interesting function returns true for numbers that are
multiples of 10, and v held {9, 5, 10, 20, 8, 47, 63, 1, 70},
then cull would return a vector that held {5, 10, 20, 8, 1, 70}
Your cull function should work properly for any interesting function,




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool interesting(unsigned n)
{
	return (n % 10 == 0);
}

vector<unsigned> cull(const vector<unsigned> & v)
{
	vector<unsigned> x;
	unsigned temp;
	for (unsigned i = 0; i < v.size(); i++)
	{
		if (interesting(v[i]))
			x.push_back(v[i]);
	}
	return x;
}


obviously this only output 10,20,70
do I need to use two loops or some other variables ??
Oct 16, 2014 at 7:34am
Please any hints
Oct 16, 2014 at 7:43am
For example, if your interesting function returns true for numbers that are
multiples of 10
then cull would return a vector that held {5, 10, 20, 8, 1, 70}


Is 8 a multiple of 10.??

To have a closer ouput, i looked at it as multiple OR factor of 10.
1
2
3
4
if(n >= 10)
   return(n%10 == 0)
else
   return (10%n == 0)


Even so, where does 8 belong??
Oct 16, 2014 at 7:48am
Aside from v[i], you should check both if v[i+1] and v[i-1] are interesting.
Note that when your current index (i) is 0 you should not check v[i-1] and when it size()-1 you should not check v[i+1] (or you will have out of range access).
Oct 16, 2014 at 7:48am
return an array
that consists of all the interesting elements of v together will all the
elements of v that are next to interesting numbers.


this is my main point
Last edited on Oct 16, 2014 at 7:59am
Oct 16, 2014 at 7:52am
Oh sorry, i forgot that part. hihi..
Oct 16, 2014 at 8:10am
This should do the job.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

vector<unsigned> cull(const vector<unsigned> & vec)
{
	vector<unsigned> x;
	for(size_t i = 0 ;i < vec.size(); i++)
	{
		if(interesting(vec.at(i)))
		{
			x.push_back(vec.at(i));
			if(i > 0 && i < vec.size() - 1)
			{
				if(intereting(vec.at(i-1)))
					x.push_back(vec.at(i -1));
				if(interesting(vec.at(i+1)))
					x.push_back(vec.at(i+1));
			}
		}
	}
	vector<unsigned>::iterator it;
	it = unique(x.begin(),x.end());
	x.resize(distance(x.begin(),it));
return x;
}

Oct 16, 2014 at 8:15am
@shadowCODE, your code will fail on 1, 10, 3 array.
Oct 16, 2014 at 8:22am
thanks @shadowCODE for your help but I am not used to write codes the way your.

anyway I understood the idea but the implementation kind of tricky
Oct 16, 2014 at 8:59am
@MiiNippa
It works for your input. I realized i didnt need to check if(interesting()) for the elements besides the interesting ones.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <iterator>
#include <algorithm>
#include <ctime>
#include <vector>
using namespace std;

bool interesting(unsigned n)
{
	return (n % 10 == 0);
}

vector<unsigned> cull(const vector<unsigned> & vec)
{
	vector<unsigned> x;
	for(size_t i = 0 ;i < vec.size(); i++)
	{
		if(interesting(vec.at(i)))
		{
			x.push_back(vec.at(i));
			if(i > 0 && i < vec.size() - 1)
			{
					x.push_back(vec.at(i-1));
					x.push_back(vec.at(i+1));
			}
		}
	}
	vector<unsigned>::iterator it;
	it = unique(x.begin(),x.end());
	x.resize(distance(x.begin(),it));
return x;
}
int main()
{
	vector<unsigned> vec;
	vec.push_back(1);
	vec.push_back(10);
	vec.push_back(3);

	vector<unsigned> test;
	test = cull(vec);

	copy(test.begin(),test.end(),ostream_iterator<unsigned>(cout," "));
	cout<<endl;
	system("pause");
	return 0;
}

10 1 3 
Last edited on Oct 16, 2014 at 9:00am
Oct 16, 2014 at 9:04am
1) It reorders elements.
2) On vector 3 10 3 20 it skips second 3

And use more common and understood erase-remove idiom:
1
2
3
4
//vector<unsigned>::iterator it;
//it = unique(x.begin(),x.end());
//x.resize(distance(x.begin(),it));
x.erase(unique(x.begin(), x.end()), x.end());
Oct 16, 2014 at 9:12am
@MiiNippa
is there a difference between,
1
2
3
vector<unsigned>::iterator it;
it = unique(x.begin(),x.end());
x.resize(distance(x.begin(),it));

AND
x.erase(unique(x.begin(), x.end()), x.end());
??

Also, the for loop goes through every element in the vector. I dont know why you say it skips the second 3 in
3 10 3 20 ..

Also made this change:
1
2
3
4
5
6
7
8
if(interesting(vec.at(i)))
{
    x.push_back(vec.at(i));
    if(i > 0)
        x.push_back(vec.at(i-1));
    if(i < vec.size() - 1)
	x.push_back(vec.at(i+1));
}
Last edited on Oct 16, 2014 at 9:17am
Oct 16, 2014 at 9:23am
is there a difference between,
No, aside from that second one is more common form.

I dont know why you say it skips the second 3 in
Yeah, faulty vectors is not that predictable, but 3, 10, 3 still skips: http://ideone.com/mIfaT4

Also made this change
Good, now you need only one change and get rid of unique().
Oct 16, 2014 at 10:05am
@MiiNipaa
I think i have fixed everything and gotten rid of unique
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
vector<unsigned> cull(const vector<unsigned> & vec)
{
	vector<unsigned> x;
	for(size_t i = 0 ;i < vec.size(); i++)
	{
		if(interesting(vec.at(i)))
		{
			if(i > 0)
				if(!binary_search(x.begin(),x.end(),vec.at(i-1)))
					x.push_back(vec.at(i-1));

			if(!binary_search(x.begin(),x.end(),vec.at(i)))
				x.push_back(vec.at(i));

			if(i < vec.size() - 1)
				x.push_back(vec.at(i+1));
		}
	}
	return x;
}


I thought i had solved this problem from the beginning. Thank you
Last edited on Oct 16, 2014 at 10:08am
Oct 16, 2014 at 10:11am
1) binary search works only for sorted sequences.
2) The aim is to allow repeating variables and you are trying to explicitely prohibit this
3) if(i > 0) and if(i < vec.size() - 1) should not be nested
4) Do not use checked access if all indices are guaranteed to fall into vector.

Now you have duplicates and losses
http://ideone.com/Du6I6e

Just think, what conditions should be true for number to be pushed into resulting vector?
Last edited on Oct 16, 2014 at 10:15am
Oct 16, 2014 at 4:44pm
Thank you guys!

this what I am getting

10 5 20 20 10 8 70 1


10 and 20 duplicated

seems hard problem to me
Oct 16, 2014 at 4:57pm
It is not hard if you do it straigtforward way:

You need to save element if:
* It is interesting  
      or  
* Previous element is interesting  
      or  
* Next element is interesting  

So you can write:
1
2
3
4
5
6
bool save =
    interesting(in[ i ])
        ||
    interesting(in[i-1])
        ||
    interesting(in[i+1]);
We still need to deal with possible out of bound access. So this is a good place to use ternary operator: (i>0 ? interesting(in[i-1]):false) — if i == 0 then apparently previous value should not be counted as interesting

So our condition looks like:
1
2
3
bool save =    interesting(in[ i ])       ||
      (i>0   ? interesting(in[i-1]):false)||
      (i<sz-1? interesting(in[i+1]):false);

Alternative approach (without ternary operator):
1
2
3
4
5
bool save = interesting(in[ i ]);
if(i>0)
    save = save || interesting[i-1];
if(i<sz-1)
    save = save || interesting(in[i+1]);


Then you just need to do:
1
2
if(save)
    x.push_back(in[i]);
Last edited on Oct 16, 2014 at 4:57pm
Oct 17, 2014 at 7:06am
Thanks, I hope this will work even if the interesting function is dealing with different thing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
vector<unsigned> cull(const vector<unsigned> & v)
{
	vector<unsigned> x;
	bool save;
	
	for (unsigned i = 0; i < v.size(); i++)
	{
		 	

			save = interesting(v[i]);
			if (i>0)
				save = save || interesting(v[i - 1]);
			if (i<v.size() - 1)
				save = save || interesting(v[i + 1]);

		if (save)
			x.push_back(v[i]);
	}
	return x;
}
Topic archived. No new replies allowed.