vector.erase() and finding mid position

Hello everyone. Im making a programm for "guess number game"
I have a little problem with vector.erase() and finding the mid position of a set of elements in a vector.

For example:
I have 10 numbers in a vector <int> (1, 2, 3, 4, 5, 6, 7, 8, 9, 10). Now I take the mid position and ask "Is your number equal or less than 5?"
If the answer is yes, the programm deletes a section and now the current values are (1, 2, 3, 4, 5), if not so the values are (6, 7, 8, 9, 10).

Im trying to do this in code but I am failing. I think that I have the problem because i am using .erase() in a incorrectly way.

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
int main()
{
	vector <int> numbers;
	char answer_key;
	for (int i = 1; i <= 100; ++i)
	{
		numbers.push_back(i);
	}

	int n_size = numbers.size(); // numero de elementos
 
/*. .......  */

		if (n_size % 2 == 0) // Only if the number of elements is pair...
		{ 
			int mid = (n_size / 2) - 1; // Mid position of the set of values.
			cout << "Is the number equal or less than " << numbers[numbers.size() / 2 - 1] << " (y / n)? "; // Ask for the mid value.
			if (answer_key == 'y')
			{
				numbers.erase(mid + 1, numbers.end()); // DELETES THE VALUES BETWEEN [(n/2) + 1, n] for only use the first n/2 values.
			}
			else if (answer_key == 'n')
			{
				numbers.erase(numbers.begin(), mid); //DELETES THE VALUES BETWEEN [1, n/2] for only use the values after n/2 + 1.
			}
		}



I would appreciate if someone would help me solve this problem.
Last edited on
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
#include <iostream>
#include <vector>
#include <numeric>

int main()
{
    std::vector<int> numbers(10) ; // declare a vector of 10 numbers
    std::iota( numbers.begin(), numbers.end(), 1 ) ; // fill it with 1 .. 10

    while( numbers.size() > 1 )
    {
        std::size_t mid_pos = numbers.size() / 2 ;
        std::cout << "is the number less than " << numbers[mid_pos] << " ? " ;
        char ans ;
        std::cin >> ans ;
        std::cout << ans << '\n' ;

        if( ans == 'y' || ans == 'Y' ) numbers.resize(mid_pos) ;
        else numbers = { numbers.begin() + mid_pos, numbers.end() } ;

        for( int n : numbers ) std::cout << n << ' ' ;
        std::cout << '\n' ;
    }

    std::cout << "the number is: " << numbers[0] << '\n' ;
}

http://coliru.stacked-crooked.com/a/5ea07efd8b480b57

Now try doing this without using a vector. (Hint: keep track of the minimum and maximum values that are left.)
@agusx, you didn't specify what the problem is. Infinite loop? Perhaps an off-by-one index issue in calcuation. Use a small example, printing out the calculated mid index and the value at that index to confirm your logic.

I'm surprised your code is even compiling because you didn't use two iterators
numbers.erase(mid + 1, numbers.end()); <-- mid+1 is not an iterator.

Also, if the mid calculation happens to be the end of the vector, then the +1 could cause an issue (half your code is missing so it's unclear).

An example with erase using '<' instead of '<=', thus making it safer against +1 calculations:

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
48
49
50
51
52
#include <iostream>
#include <vector>
#include <random>

using namespace std;

void Show(const vector<int>& v)
{
    for(auto& n : v)
        cout << n << ' ';
    cout << endl;
}

int main() 
{
    int limit = 10;
    vector<int> numbers;
    numbers.reserve(limit);
    for (int i=1; i<=limit; ++i)
        numbers.push_back(i);
    
    random_device rd;
    int n = rd() % limit + 1;

    cout << "random n is " << n << endl;
    Show(numbers);
    
    cout << boolalpha;
    int mid, midnum;
    int attempts=10;   // To stop infinite loop in case of logic issue
    while (attempts--)
    {
        mid = numbers.size()/2;
        midnum = numbers[mid];
        cout << endl;
        cout << "mid is "<<mid<<"; midnum is "<<midnum << endl;
        cout << "n < midnum? " << (n<midnum) << endl;
        if (n < midnum)
        {
            numbers.erase(numbers.begin()+mid, numbers.end());
        }
        else
        {
            numbers.erase(numbers.begin(), numbers.begin()+mid);
        }
        Show(numbers);
        if (numbers.size()<=1)
            break;
    }    
    
    return 0;
}


the loop condition can be replaced with while(true), but it's good practice to limit the iterations just in case the logic isn't finished.

sample output:
random n is 9
1 2 3 4 5 6 7 8 9 10 

mid is 5; midnum is 6
n < midnum? false
6 7 8 9 10 

mid is 2; midnum is 8
n < midnum? false
8 9 10 

mid is 1; midnum is 9
n < midnum? false
9 10 

mid is 1; midnum is 10
n < midnum? true
9 
Thanks a lot JLBorges and icy1!

Yes icy1, you are right, I didn't explain so well my problem. It was exactly that was I need, thanks!
Last edited on
Topic archived. No new replies allowed.