Vector Subscript out of Range. Comparing Elements of Vectors - c++

So I have a vector like this
All_Pos={0,10,15,24,30,33,66}
And three smaller vectors that contain the numbers from the previous vector, let's say
Vec_Lin={0,15}
Vec_Circ={24,33,66}
Vec_Arc={10,30}
I want to make something like this:
All_Pos[0]=Vec_Lin[0]? YES -> Do something
All_Pos[1]=Vec_Lin[1]?No
All_Pos[1]=Vec_Circ[0]?No
All_Pos[1]=Vec_Arc[0]?Yes -> Do Something
Ans so on, until i finish my All_Pos. The problem is that i get vector out of range and i don't know how to fix that.
int counter_linie=0;
int counter_cerc=0;
int counter_arc=0;
for (int p = 0; p < All_pos.size(); p++)
{
if(All_pos[p] == Vec_Lin[counter_linie])
{
//Do something
counter_linie++;
}
if (All_pos[p] == Vec_circ[counter_cerc])
{
//Do something
counter_cerc++;
}
if (All_pos[p] == Vec_Arc[counter_arc])
{
/Do something
counter_arc++;
}
}

You should check for out of range. [] operator works ,when indexing is in limits from '0' to vector.size().
void process_vector(void)
{
std::vector<int> All_Pos = { 0,10,15,24,30,33,66 };
std::vector<int> Vec_Lin = { 0,15 };
std::vector<int> Vec_Circ = { 24,33,66 };
std::vector<int> Vec_Arc = { 10,30 };
int counter_linie = 0;
int counter_cerc = 0;
int counter_arc = 0;
for (int p = 0; p < All_Pos.size(); p++) {
if (counter_linie< Vec_Lin .size() && All_Pos[p] == Vec_Lin[counter_linie])
{
//Do something
counter_linie++;
}
if (counter_cerc < Vec_Circ.size() && All_Pos[p] == Vec_Circ[counter_cerc])
{
//Do something
counter_cerc++;
}
if (counter_arc < Vec_Arc.size() && All_Pos[p] == Vec_Arc[counter_arc])
{
// Do something
counter_arc++;
}
}
std::cout << counter_linie << " " << counter_cerc << " " << counter_arc << std::endl;
}

You are trying to access elements that don't exist in your smaller vectors.
Vec_circ can only be accessed with indices 0, 1 and 2, but after three successful checks for Vec_circ in your loop counter_cerc will be 3.
Trying to access Vec_circ[3] then leads to the error.
You need a mechanism that prevents this case.

You should step through your code with a debugger to see the problem.
Initially the values are:
int counter_linie=0;
int counter_cerc=0;
int counter_arc=0;
After the first iteration the values are:
counter_linie=1;
counter_cerc=0;
counter_arc=0;
After the second iteration the values are:
counter_linie=1;
counter_cerc=0;
counter_arc=1;
After the third iteration the values are:
counter_linie=2;
counter_cerc=0;
counter_arc=1;
And now you try to read
Vec_Lin[2]
in
if(All_pos[p] == Vec_Lin[counter_linie])
That's your problem. Add a check into the if conditions.
if(counter_linie < Vec_Lin.size() && All_pos[p] == Vec_Lin[counter_linie])

Related

C++ If I sort a vector, how can I get another vector to align with that vector? [duplicate]

This question already has answers here:
Suppose we have two std::vectors v1 and v2 and we dont want to combine these in a struct. How to transform v2 the same way v1 was transformed by sort?
(3 answers)
Closed 1 year ago.
I created this little project in C++ for a basketball 'gameish' thing. One thing I wanted to implement was a funciton that allowed one to see who had the highest or lowest stats out of all of the players, in this case, specifically, points per game (ppg).
I broke up the stat components of the players and the names of the players into two different vectors, vector <vector <string> > names and vector <vector <double>> stats. I made it so that names[0] correlated to stats[0], so LeBron and his stats would be represented by say 1. I figured out how to sort the vectors by descending or ascending order, but when I sort a vector, say stats[0], the order is now different from the original order, and so it doesn't align with names[0]. So when I print stats[0][i] belongs to names[0][i] it no longer is true, as the two are no longer 'connected'. I've tried to troubleshoot this myself first, but came up empty, and then tried searching online for an answer which I haven't found, perhaps I didn't look hard enough. What do I do to make it so that the now mixed-up order of the stats vector can be written out correctly?
This code I created, seen below, works sometimes, for ppg it works until around 20. I tried to create it so that you could use any vector .
void sorting_test(bool ascend, int number, vector <double> statistic) {
vector <vector <double>> ppg_desc {
{},//ppg
{},//slot
{},//locked
};
//
for (int i = 0; i < statistic.size(); i++) {
ppg_desc[0].push_back(statistic[i]);
ppg_desc[1].push_back(i);
}
sort(ppg_desc[0].begin(), ppg_desc[0].end());
if (ascend == false)
reverse(ppg_desc[0].begin(), ppg_desc[0].end());
//
for (int i = 0; i < statistic.size(); i++) {
//
bool lok = false;
//
for (int f = 0; f < statistic.size(); f++) {
//
for (int d = 0; d < ppg_desc[2].size(); d++) {
//
if (i == ppg_desc[1][d]) {
//
lok = true;
//
for (int s = f + 1; s < statistic.size(); s++) {
//
if (statistic[s] == ppg_desc[0][i]) {
lok = false;
f = s;
if (f >= statistic.size()) f = statistic.size() - 1;
}
}
}
}
//
//if (stats[6][f] == ppg_desc[0][i] && lok == false) ppg_desc[1][i] = f, ppg_desc[2].push_back(ppg_desc[1][i]), cout<<i<<"-";
if (statistic[f] == ppg_desc[0][i] && lok == false) ppg_desc[1][i] = f, ppg_desc[2].push_back(i);
}
}
//
for (int i = 0; i < number; i++) {
cout << i << ".) " << ppg_desc[0][i] << " - " << names[0][ppg_desc[1][i]] << endl;
}
//
}
What you basically need is a list of the indices, sorted by one of the vectors content.
This can be achieved with a variant of std::sort taking function objects / lambdas; something like this:
std::vector<int> score = {2,4,3};
std::vector<std::string> names = {"a", "b", "c"};
std::vector<int> V(N);
std::iota(V.begin(),V.end(), 0); // fill V with values increasing by 1
std::sort(V.begin(),V.end(), [&](int i,int j){return score[i]<score[j];} );
std::cout << "Names sorted by score: " << names[V[0]] << ", "<< names[V[1]] << ", "<< names[V[2]] << "\n";
As you can see, you can use the indices in V, now sorted by score, as index into names.
See example at cpp.sh
Inspiration: https://stackoverflow.com/a/40183830
An alternative solution, as suggested in comments, would be to include all values that belong together (both names and scores in my example) into a struct, then have a vector of this struct, and then again use above sort method with a specialized sorting function.
struct Player { std::string name; int score; }
std::vector<Player> players;
//... insert some players
std::sort(players.begin(), players.end(), [](auto const & p1, auto const & p2) { return p1.score < p2.score; });
// .. and now all your data is sorted by score!

How to compare values of two vectors

Is anybody there who has a code on how to compare values of two arrays ?
I have two vectors and I am looking for the biggest and equal value of the both list.
Here is the code:
void fractionInLowestTerm(int fNumerator, int fDenominator)
{
//let's get the dividers of fNumerator and fDenominator
std::vector<int> dividerOfNumerator;
std::vector<int> dividerOfDenominator;
for (int i = 1; i <= fNumerator; i++) {
if (fNumerator % i == 0) {
dividerOfNumerator.push_back(i);
}
}
for (int j = 1; fDenominator <= j; j++) {
if (fDenominator % j == 0) {
dividerOfDenominator.push_back(j);
}
}
// let's get the greatest common divider of a and b;
int pgcd = 1;
// I do not know how to compare the values of dividers to get the greatest common value on a and b there is the code I started writing to get that
for (int m = 0; m <= dividerOfNumerator.size() && m <= dividerOfDenominator.size(); m++) {
}
}
If I understand the problem correctly, you want to compare the elements in two arrays for each index and save the greater one into a third array. In this case, just use your favourite max function for each index. For example:
void compare(int* array1, int* array2, int* array3, int size)
{
for (int member = 0; member < size; ++member) {
array3[member] = std::max(array1[member], array2[member]);
}
}
or if you want to compare lists and write into third array that which array has bigger value in that index you can use following code
void compare(int* array1, int* array2, int* array3, int size)
{
for (int member = 0; member < size; ++member) {
if (array1[member] > array2[member]) {
array3[member] = 1;
}
else if (array1[member] < array2[member]) {
array3[member] = 2;
}
else if (array1[member] == array2[member]) {
array3[member] = 0;
}
}
}
Since the vectors containing the divisors are already sorted, you can use the std::set_intersection algorithm like this:
std::vector<int> commonDivisors;
std::set_intersection(dividerOfNumerator.begin(), dividerOfNumerator.end(),
dividerOfDenominator.begin(), dividerOfDenominator.end(),
std::back_inserter(commonDivisors));
int pgcd = commonDivisors.back(); // guaranteed to be non-empty since 1 is always a divisor
Here's a demo.
Hello as you can see on the function name I wanted to write a function which put a function on the lowest term. I wanted to go through the gcd but I saw that it would consumes too much memory so here is what I've done. If it can help any member of the forum.
void fractionInLowestTerm(int fNumerator, int fDenominator){
//let's get on the divider of the number
for (int i = 1; i < fNumerator and i <fDenominator; i++) {
if (fNumerator%i == 0 and fDenominator%i == 0) {
fNumerator /= i;
fDenominator /= i;
i = 1;
}
}
}

Problems with vectors, how to remove the arrays in my vectors?

I have created a function that creates all the possible solutions for a game that I am creating... Maybe some of you know the bullcow game.
First I created a function that creates a combination of numbers of max four integers and the combination can't have any repeating number in it... like...
'1234' is a solution but not '1223' because the '2' is repeating in the number. In total there is 5040 numbers between '0123' and '9999' that haven't repeating numbers.
Here is my function:
std::vector <std::array<unsigned, 4>> HittaAllaLosningar(){
std::vector <std::array<unsigned, 4>> Losningar;
for (unsigned i = 0; i < 10; i++) {
for (unsigned j = 0; j < 10; j++) {
for (unsigned k = 0; k < 10; k++) {
for (unsigned l = 0; l < 10; l++) {
if (i != j && i != k && i != l && j != k && j != l && k != l) {
Losningar.push_back({i,j,k,l});
}
}
}
}
}
return Losningar;
}
Now let's say I have the number '1234' and that is not the solution I am trying to find, I want to remove the solution '1234' from the array since that isn't a solution... how do I do that? have been trying to find for hours and can't find it. I have tried vector.erase but I get errors about unsigned and stuff... also its worth to mention the guesses are in strings.
What I am trying to do is, to take a string that I get from my program and if it isn't a solution I want to remove it from the vector if it exists in the vector.
Here is the code that creates the guess:
std::string Gissning(){
int random = RandomGen();
int a = 0;
int b = 0;
int c = 0;
int d = 0;
for (unsigned i = random-1; i < random; i++) {
for (unsigned j = 0; j < 4; j++) {
if (j == 0) {
a = v[i][j];
}
if (j == 1) {
b = v[i][j];
}
if (j == 2) {
c = v[i][j];
}
if (j == 3) {
d = v[i][j];
}
}
std::cout << std::endl;
AntalTry++;
}
std::ostringstream test;
test << a << b << c << d;
funka = test.str();
return funka;
}
The randomgen function is just a function so I can get a random number and then I go in the loop so I can take the element of the vector and then I get the integers of the array.
Thank you very much for taking your time to help me, I am very grateful!
You need to find the position of the element to erase.
std::array<unsigned, 4> needle{1, 2, 3, 4};
auto it = std::find(Losningar.begin(), Losningar.end(), needle);
if (it != Losningar.end()) { Losningar.erase(it); }
If you want to remove all the values that match, or you don't like checking against end, you can use std::remove and the two iterator overload of erase. This is known as the "erase-remove" idiom.
std::array<unsigned, 4> needle{1, 2, 3, 4};
Losningar.erase(std::remove(Losningar.begin(), Losningar.end(), needle), Losningar.end());
To erase from a vector you just need to use erase and give it an iterator, like so:
std::vector<std::array<unsigned, 4>> vec;
vec.push_back({1,2,3,4});
vec.push_back({4,3,2,1});
auto it = vec.begin(); //Get an iterator to first elements
it++; //Increment iterator, it now points at second element
it = vec.erase(it); // This erases the {4,3,2,1} array
After you erase the element, it is invalid because the element it was pointing to has been deleted. Ti continue to use the iterator you can take the return value from the erase function, a valid iterator to the next element after the one erased, in this the case end iterator.
It is however not very efficient to remove elements in the middle of a vector, due to how it works internally. If it's not important in what order the different solution are stored, a small trick can simplify and make your code faster. Let's say we have this.
std::vector<std::array<unsigned, 4>> vec;
vec.push_back({1,2,3,4});
vec.push_back({4,3,2,1});
vec.push_back({3,2,1,4});
To remove the middle one we then do
vec[1] = vec.back(); // Replace the value we want to delete
// with the value in the last element of the vector.
vec.pop_back(); //Remove the last element
This is quite simple if you have ready other functions:
using TestNumber = std::array<unsigned, 4>;
struct TestResult {
int bulls;
int cows;
}
// function which is used to calculate bulls and cows for given secred and guess
TestResult TestSecretGuess(const TestNumber& secret,
const TestNumber& guess)
{
// do it your self
… … …
return result;
}
void RemoveNotMatchingSolutions(const TestNumber& guess, TestResult result)
{
auto iter =
std::remove_if(possibleSolutions.begin(),
possibleSolutions.end(),
[&guess, result](const TestNumber& possibility)
{
return result == TestSecretGuess(possibility, guess);
});
possibleSolutions.erase(iter, possibleSolutions.end());
}
Disclaimer: it is possible to improve performance (you do not care about order of elements).

C++ Array comparison and printing difference

The thing i want to do is compare two arrays, A and B, and post numbers from array B that doesn't appear in array A.
http://pastebin.com/u44DKsWf My full code.
Problem starts at line 42 i think.
int writingPosition = 1;
for (int c = 1; c<=firstArrayLength; c++)
{
for(int z = 1; z>secondArrayLength; z++)
{
if (firstArray[c] != secondArray[z])
{
thirdArray[writingPosition] = secondArray[z];
writingPosition++;
}
if (firstArray[c] == secondArray[z])
{
thirdArray[c] == '0'; // NEED FIXING I GUESS
}
}
}
The idea is that i mark numbers that dont fit my task as '0', so later on i can print array while ignoring 0.
Thank you!
You could use binary_search from algorithm module from C++ Standard Library.
Note this works with std::vector aswell.
Live demo
#include <array>
#include <iostream>
#include <algorithm>
int main()
{
std::array<int, 3> firstArray { 1, 3, 5 }; // stack based array like int[3]
std::array<int, 3> secondArray { 2, 3, 4 };
// Sort first array to be able to perform binary_search on it
std::sort(firstArray.begin(), firstArray.end());
for (const auto secondArrayItem : secondArray)
{
// Binary search is a very efficient way of searching an element in a sorted container of values
if (std::binary_search(firstArray.begin(), firstArray.end(), secondArrayItem) == false)
{
std::cout << "Item " << secondArrayItem << " does not exist in firstArray" << std::endl;
}
}
return 0;
}
Correction to your code should be somewhat like :
int writingPosition = 1;
for (int c = 1; c<=firstArrayLength; c++)
{
for(int z = 1; z<=secondArrayLength; z++)
{
if (firstArray[c] != secondArray[z])
{
thirdArray[writingPosition] = secondArray[z];
writingPosition++;
}
if (firstArray[c] == secondArray[z])
continue;
}
}
On a side note : Prefer using 0 as the base index for arrays.
There are many things wrong with your code.
Arrays of size s always range from 0 to s-1, so in your case you should use
for(int g = 0; g<50; g++)
i.s.o.
for(int g = 0; g<=50; g++)
and similar for the other arrays
Secondly, you fill the third array with char elements, and then compare them to int
thirdArray[c] == '0';
and later
if(thirdArray[g] != 0)
Either use '0' or 0 both times, but don't mix them up.
But the general algorithm doesn't make much sense either, you're overriding third array both based on index c as index z.
Also the range on z makes little sense.
(I assume this is homework or at least you're trying to study, so won't simply give a solution)
why don't you store the numbers that doesn't exist in a string and then you print the string from cout? this is how you can do this:
string output = "";
bool isFound = false;
for (int c = 1; c<=secondArrayLength; c++)
{
isFound = false;
for(int z = 1; z>firstArrayLength; z++)
{
if (secondArray[c] == firstArray[z])
{
isFound = true;
}
}
if(!isFound)
output+=(secondArray[c].str()+" ");
}
cout<<output;
try this it must work fine

Getting an array of structures by using an element of structure

I have an array which holds a structure like:
struct Point
{
int x;
int y;
}
Point array_of_structure[10] ;
for(int i=0;i<10;i++)
{
array_of_structure[i].x = i*2;
}
I want to get the structure which holds x value of 6. In this way I access the y value of that structure. How can I do it?
It's something like the below:
Point p = Get the structure which contains x value of 6;
int c = p.y;
Here is a sample solution. But I need a better idea or ideas.
for(int i=0;i<10;i++)
if(array_of_structure[i].x==6)
return array_of_structure[i].y;
I thought about maybe pointers make this job but I'm not sure about it. I cannot figure out how to solve this problem.
Standard library provides a function std::find_if which can be used to find an item without a loop. As a learning exercise, however, you could do it using a loop as described below:
You can iterate your array of structs until you find the x of interest. You can use a pointer or an index, depending on your preferences. You need to set a flag indicating if you have found your item or not.
Here is how you can do it with a pointer:
struct Point *ptr;
bool found = false;
for (ptr = array_of_structure ; !found && ptr != &array_of_structure[10] ; ptr++) {
found = (ptr->x == x);
}
if (found) {
cout << ptr->y << endl;
}
Here is how you can do it with an index:
int index ;
bool found = false;
for (index = 0 ; !found && index != 10 ; index++) {
found = (array_of_structure[index].x == x);
}
if (found) {
cout << array_of_structure[index].y << endl;
}
Note: if you are looking for a find_if solution, here is an answer that explains this approach.