Can anyone explain how to use unique( ) in the vector? - c++

#include<bits/stdc++.h>
using namespace std;
int main() {
vector <int> v = {1, 2 , 3, 2 , 1};
cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << endl;
sort(v.begin(), v.end());
cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << endl;
unique(v.begin(), v.end());
cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << endl;
}
Output is
1 2 3 2 1
1 1 2 2 3
1 2 3 2 3
I'm not understanding what is unique function and how it is working ??

Aside the fact, that bits/stdc++.h is not the proper header when taking C++ standard into account (please use iostream, vector and algorithm).
From: https://en.cppreference.com/w/cpp/algorithm/unique
Eliminates all except the first element from every consecutive group of equivalent elements from the range [first, last) and returns a past-the-end iterator for the new logical end of the range.
Removing is done by shifting the elements in the range in such a way that elements to be erased are overwritten
Thus the end of the vector might contain "garbage", but this is fine, as the new end of it is also returned.
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
vector <int> v = {1, 2 , 3, 2 , 1};
cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << endl;
sort(v.begin(), v.end());
cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << endl;
auto new_end = unique(v.begin(), v.end());
auto b = v.begin();
while (b!=new_end) {
std::cout << *b++ << " ";
}
std::cout << "\n";
return 0;
}
demo

Related

Cout printing with array pointers - weird behavior

I was playing around with pointers and got results I did not expect:
#include <iostream>
#include <vector>
int main() {
int arr[4] = { 1, 2, 3, 4 };
int* pArr = arr;
std::cout << "First number: " << *pArr << " at address: " << pArr;
pArr++;
std::cout << "\nSecond number: " << *pArr << " at address: " << pArr;
pArr++;
std::cout << "\nThird number: " << *pArr << " at address: " << pArr;
pArr++;
std::cout << "\nFourth number: " << *pArr << " at address: " << pArr;
int* pArr2 = arr;
std::cout << "\n"
<< *pArr2++ << "\n"
<< *pArr2++ << "\n"
<< *pArr2++ << "\n"
<< *pArr2++ << "\n";
/*
int* pArr2 = arr;
std::cout << "\n"
<< ++ * pArr2 << "\n"
<< * ++pArr2 << "\n";
*/
}
The two different results:
1 2 3 4 - as expected using the first method
4 3 2 1 - using cout with multiple arguments I do not know the proper name.
So my question is - why does this happen? Using multiple cout statements results in expected for me code, while using just 1 cout results in backwards solution.
As a side note, another confusing thing to me is that pre-increment results in all values being equal. In the commented bit of code, the result is 3 3, no matter the ++ placement with respect to the *.
This code:
std::cout << "\n" << *pArr2++ << "\n";
std::cout << "\n" << *pArr2++ << "\n";
has a well defined order of modifications to pArr and will print
1
2
But this code:
std::cout << "\n" << *pArr2++ << "\n" << *pArr2++ << "\n";
invokes undefined behavior before c++17, because there are multiple modifications to pArr2 that are unsequenced. The program has UB, so it could print anything.
From c++17, there is a sequence point between the modifications, and the above code is guaranteed to print:
1
2

Keeping a reference to a vector element valid after resizing

If we make a reference to a vector element and then resize the vector, the reference is no longer valid, the same happens with an iterator:
std::vector<int> vec{0, 1, 2, 3, 4, 5};
int& ref = vec[0];
auto itr = vec.begin();
cout << ref << " " << *itr << endl;
vec[0] = 7;
cout << ref << " " << *itr << endl;
vec.resize(100);
vec[0] = 3;
cout << ref << " " << *itr << endl;
Prints out:
0 0
7 7
0 0 // We expected a 3 here
And I know that it would be more practical to just keep a reference to the vector itself and call vec[0], but just for the sake of questioning, is it possible to keep an object that will always be vec[0] even if the object is moved?
I've tried writing a small helper class to help with this, but I'm unsure if this is the best method or if it can even fail?
template<typename T>
struct HelperClass
{
std::vector<T>& vec;
size_t element;
HelperClass(std::vector<T>& vec_, size_t element_) : vec(vec_) , element(element_) {}
// Either define an implicit conversion from HelperClass to T
// or a 'dereference' operator that returns vec[0]
operator T&() { return vec.at(element); }
T& operator*() { return vec.at(element); }
};
And use it by either the implicit conversion to T& or by the 'dereference' operator:
std::vector<int> vec{0, 1, 2, 3, 4, 5};
int& ref = vec[0];
auto itr = vec.begin();
HelperClass<int> hlp = HelperClass<int>(vec, 0); // HelperClass
cout << ref << " " << *itr << " " << hlp << " " << *hlp << endl;
vec[0] = 7;
cout << ref << " " << *itr << " " << hlp << " " << *hlp << endl;
vec.resize(100);
vec[0] = 3;
cout << ref << " " << *itr << " " << hlp << " " << *hlp << endl;
Which already prints what was excepted:
0 0 0 0
7 7 7 7
0 0 3 3
So is there a better way to do this aside from having a helper class and can the helper class be unreliable in some cases?
I've also come across this thread in reddit, but it seems that they do not discuss the helper class there
The one thing you could do is have a vector of pointers rather than a vector of instances. That of course has its own passel of issues but if you must have object references survive a vector resize that will do it.
Any reallocation of the vector will invalidate any pointers, references and iterators.
In your example, your HelperClass is useless in sense that this:
cout << ref << " " << *itr << " " << hlp << " " << *hlp << endl;
is the same as:
cout << ref << " " << *itr << " " << vec[0] << " " << vec[0] << endl;
If a reallocation happens, just use the iterator interface .begin() .end() to access again the iterators.

Separate statement to print each operand

I'm new to C++ and learning from the C++ Primer book. I would like to know how I would separate statement to print each operand form the following code:
#include <iostream>
int main()
{
std::cout << "Enter two numbers: " << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The numbers " << v1 << " and " << v2 << " multiplied are equal to " << v1 * v2 << std::endl;
}
I think I am meant to simplify the last statement but unsure how. If anyone would be able to help, it would be very helpful for my learning.
Just do std::cout << for each operand.
std::cout << "The numbers ";
std::cout << v1;
std::cout << " and ";
std::cout << v2;
std::cout << " multiplied are equal to "
std::cout << v1 * v2;
std::cout << endl;

Print amount of repeated numbers in array c++

I was wondering how to print the amount of repeated numbers from a randomly generated array with an array size of 10, and numbers from 1 - 10.
Example:
Array1: 1 7 6 5 6 7 8 10 9 8
Number of Patterns: 3
(Because it consists of; 2 six, 2 seven, 2 eights)
So far for my code I have done this
#include <iostream>
#include <iomanip>
#include <string>
#include <time.h>
#include "Source.h"
#include <algorithm>
using namespace std;
void main()
{
//START OF PROGRAM CODE\\
//Declaritions\\
const int ArraySize = 10;
int arrayMain[ArraySize];
int array1[ArraySize];
int i = 0;
int j = 0;
int k = 0;
//End of Declairations\\
//Store Random Number in Array\\
srand((unsigned)time(0));
for (i = 0; i < 10; i++)
{
arrayMain[i] = (rand() % 10) + 1;
array1[i] = arrayMain[i]; //Copy mainarray to array1
}
for (j = 0; j != ArraySize; j++)
{
sort(array1, array1 + ArraySize); //Sort the array
}
//End of Store Random Number in Array\\
//Program Output\\
cout << "ArrayMain: " << arrayMain[0] << " " << arrayMain[1] << " " << arrayMain[2] << " " << arrayMain[3] << " " << arrayMain[4] << " " << arrayMain[5] << " " << arrayMain[6] << " " << arrayMain[7] << " " << arrayMain[8] << " " << arrayMain[9] << " " << endl;
cout << "Array1: " << array1[0] << " " << array1[1] << " " << array1[2] << " " << array1[3] << " " << array1[4] << " " << array1[5] << " " << array1[6] << " " << array1[7] << " " << array1[8] << " " << array1[9] << " " << endl;
//cout << "Number of Patterns: " << <DATA TO INPUT> << endl;
//END OF PROGRAM CODE\\
}
There's a very simple pattern. You could use an array (I'll be using a vector) of a size equal to the range of possible random numbers
//creates a vector ArraySize big with all elements initialized to 0
std::vector<int> results(ArraySize, 0);
Then, go through your loop and use the random numbers as indexes and increment the values
for(int i = 0; i < 10; i++)
results[(rand() % 10)]++;
Finally, to count how many patterns there are
std::cout << "Number of patterns: ";
std::cout << std::count_if(results.begin(), results.end(), [](int i){return i > 1;});
std::cout << std::endl;

C++ || Adding two matrice arrays - easier way to output?

I'm doing some self study on C++ and have just being doing some chapter on arrays, loops etc. There are a bunch of exercises and the one I'm referencing is quite simple. Initialise two matrices of two rows and three columns.
Output the contents of the matrices (formatted as specified), then perform an addition which is held in a third matrice. Output the third array with the addition done. The code I have works but I'm thinking there's a better way to do the output rather than address each matrice element? I'm thinking of another loop given this is the chapter preceding the exercise, or is this way acceptable?
#include <iostream>
#include <string>
using namespace std;
int main()
{
int amatrix[2][3]=
{
{-5, 2, 8},
{1, 0, 0},
};
int bmatrix[2][3]=
{
{1, 0, 2},
{0, 3, -6},
};
int cmatrix[2][3]=
{
{0, 0, 0},
{0, 0, 0},
};
//add generated matrices
for (int i = 0; i <= 1; i++)
{
for (int j =0; j <= 2; j++)
{
cmatrix[i][j]=amatrix[i][j]+bmatrix[i][j];
}
}
//output to screen - NEED ADVICE FROM HERE
cout << "A= " << endl;
cout << amatrix[0][0] << ", " << amatrix[0][1] << ", " << amatrix[0][2] << endl;
cout << amatrix[1][0] << ", " << amatrix[1][1] << ", " << amatrix[1][2] << endl << endl;
cout << "B= " << endl;
cout << bmatrix[0][0] << ", " << bmatrix[0][1] << ", " << bmatrix[0][2] << endl;
cout << bmatrix[1][0] << ", " << bmatrix[1][1] << ", " << bmatrix[1][2] << endl << endl;
cout << "C= " << endl;
cout << cmatrix[0][0] << ", " << cmatrix[0][1] << ", " << cmatrix[0][2] << endl;
cout << cmatrix[1][0] << ", " << cmatrix[1][1] << ", " << cmatrix[1][2] << endl << endl;
}
cout << amatrix[i][j] in a for loop