Create two vectors contain the same elements in different order - c++

Is it possible to create a vector from elements of another vector so that changing an element by index in one of the vectors results in a change in the corresponding element in the second vector?
std::vector<double> temp_1 = {1, 4};
std::vector<double> temp_2;
temp_2.resize(3);
temp_2[0] = temp_1[1];
temp_2[1] = temp_1[0];
temp_1[0] = 55;
>>> temp_1 =[55,4]
>>> temp_2 =[4,55]

I can be done using pointers or reference wrappers, though note that any reallocation of the referenced vector will render the references invalid. However, if no reallocations are involved, it should be fine.
#include <vector>
#include <functional>
#include <iostream>
int main(int, char*[])
{
std::vector<int> x{1,2,3};
std::vector<std::reference_wrapper<const int>> y {
x[2], x[0], x[1]
};
std::cout << "y before modifying x\n";
for (auto el: y) {
std::cout << el << '\n';
}
x[1] = 8;
std::cout << "y after modifying x\n";
for (auto el: y) {
std::cout << el << '\n';
}
}
https://godbolt.org/z/d41nxPffz

Related

How to get frequency of std:vectors in C++?

I have 5 vectors. I want to check how many times these vectors exist. I used the following code to compare if 2 vectors are equal, but now I have more than 2 vectors. I want to compare all these 5 vectors together and count how many times each vector exists.
How can I do it?
The output should be:
(0,0,1,2,3,0,0,0) = 2 time(s)
(0,0,1,2,3,4,0,0) = 1 time(s)
(0,0,2,4,3,0,0,0) = 1 time(s)
(0,0,6,2,3,5,6,0) = 1 time(s)
Here is my code:
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
void checkVec(vector<int> v){
vector<int> v0;
if(v0 == v){
cout << "Equal\n";
}
else{
cout << "Not Equal\n";
}
}
int main(){
vector<int> v1={0,0,1,2,3,0,0,0};
vector<int> v2={0,0,1,2,3,4,0,0};
vector<int> v3={0,0,2,4,3,0,0,0};
vector<int> v4={0,0,1,2,3,0,0,0};
vector<int> v5={0,0,6,2,3,5,6,0};
checkVec(v1);
return 0;
}
You can use std::map counting the number of occurences of each vector:
#include <map>
#include <vector>
#include <iostream>
using vec = std::vector<int>;
int main(){
vec v1={0,0,1,2,3,0,0,0};
vec v2={0,0,1,2,3,4,0,0};
vec v3={0,0,2,4,3,0,0,0};
vec v4={0,0,1,2,3,0,0,0};
vec v5={0,0,6,2,3,5,6,0};
std::map<vec,std::size_t> counter;
// Initializer list creates copies by default
// But you should not create vX variables anyway.
for(const auto& v: {v1,v2,v3,v4,v5}){
++counter[v];
}
std::cout<<"V1 is present " <<counter[v1]<<" times.\n";
return 0;
}
V1 is present 2 times.
Well, this is a contribution for Quimby answer, but if you know how many vectors you will get at compile time, use std::array to contain all that vector. If you know it at runtime instead, use std::vector as shown below
#include <map>
#include <vector>
#include <iostream>
#include <cstddef>
int main(){
std::vector<std::vector<int>> allVector
{
std::vector<int>{0,0,1,2,3,0,0,0},
std::vector<int>{0,0,1,2,3,4,0,0},
std::vector<int>{0,0,2,4,3,0,0,0},
std::vector<int>{0,0,1,2,3,0,0,0},
std::vector<int>{0,0,6,2,3,5,6,0},
};
std::map<std::vector<int>, std::size_t> counter;
for(const auto& v : allVector)
{
++counter[v];
}
// print out the array and it's frequency
for(const auto& pr : counter)
{
std::cout << '(';
for(std::size_t i {0}; i < pr.first.size(); ++i)
{
std::cout << pr.first[i];
if(i != pr.first.size() - 1)
std::cout << ' ';
}
std::cout << ") = " << pr.second << ", ";
}
return 0;
}

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?

This is a followup of this question. The only difference is the constrain that the two vectors cannot be combined in a struct.
Suppose we have a vector
std::vector<double> v1 = {9.0,5.0,3.0,2.0,1.0};
Now we sort the vector v1. Let v2 be given by
std::vector<std::string> v2 = {"you?","are","how","there","hello"};
How to transform v2 the same way v1 was transformed by sort?
Based on this answer, you can use an array of indices to "sort" the vector of doubles, and just use the resulting index array to index the vector of strings.
#include <algorithm>
#include <iostream>
#include <string>
#include <numeric>
int main()
{
std::vector<double> v1 = {5.0,9.0,3.0,2.0,1.0};
std::vector<std::string> v2 = {"are", "you?","how","there","hello"};
// Create an array of indices, starting from 0
std::vector<int> index(v1.size());
std::iota(index.begin(), index.end(), 0);
// "Sort" the index array according to the value in the vector of doubles
std::sort(index.begin(), index.end(),
[&](int n1, int n2){ return v1[n1] < v1[n2]; });
// Output results
for (auto i : index )
std::cout << v2[i] << " " << v1[i] << ", index is " << i << "\n";
}
Output:
hello 1, index is 4
there 2, index is 3
how 3, index is 2
are 5, index is 0
you? 9, index is 1
Note:
I changed the original data to illustrate how the index array works.
The abstraction you are missing is the ability to view the vectors as one item. That's the role that a vector of indices is a proxy for in another answer.
I think it is worth mentioning that there are libraries that provide such a concept (often under the name "zip"). For example, with range-v3:
std::vector<double> v1 = {5, 9, 3, 2, 1};
std::vector<std::string> v2 = {"are", "you?", "how", "there", "hello"};
// Sort the vectors
ranges::actions::sort(ranges::views::zip(v1, v2));
// Output results
for (std::size_t i = 0; i < v1.size(); ++i)
std::cout << v2[i] << " " << v1[i] << ", index is " << i << "\n";
A possible solution uses a helper std::vector<int>:
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
template<typename T>
void MySort(std::vector<T> t, std::vector<int>& helper)
{
struct StructHelper
{
T t1;
int num;
StructHelper(T t, int i): t1{t}, num{i} {};
bool operator<(const StructHelper& other) const
{ return t1 < other.t1; }
};
std::vector<StructHelper> shVector;
for(int i=0; i<t.size(); ++i)
{
shVector.emplace_back(t[i], i);
}
std::sort(shVector.begin(), shVector.end());
helper = std::vector<int>(t.size());
for(int i=0; i<t.size(); ++i)
{
helper[i] = shVector[i].num;
}
}
template<typename T>
void MySortUsingHelper(std::vector<T>& t1, const std::vector<int>& helper)
{
if(t1.size() != helper.size()) throw std::out_of_range("not same size");
std::vector<T> t2(t1.size());
for(int i=0; i<helper.size(); ++i)
{
t2[i] = t1[helper[i]];
}
t1 = t2;
}
int main() {
std::vector<double> v1 = {9.0,5.0,3.0,2.0,1.0};
std::vector<int> helper;
MySort(v1, helper);
std::vector<std::string> v2 = {"you?","are","how","there","hello"};
MySortUsingHelper(v2, helper);
for(auto elem : v2)
{
std::cout << elem << " ";
}
return 0;
}
You can run the above code online to see the following output:
hello there how are you?

How do you use a vector in c++?

I am a beginner in c++ and I am trying to understand vectors.
I know the basic format which is:
vector <dataType> vectorName;
People are telling me that vectors are like arrays. But, what I don't
understand is that for arrays you can do this:
array[] = {1, 2, 3}
But for vectors you don't seem to get to set it to a list. Or do you have
to keep using .push_back().
Also, can you use something like vectorName[1] or not?
Can anyone explain this to me?
Thanks.
You can use the style if you use C++11 or later.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec = {1, 2, 3};
std::cout << vec[1] << std::endl;
return 0;
}
The whole purpose of vectors is to be "infinite", so you don't have to redefine it everytime you need to expand it.
push_back is made so you can add/expand to the array without redefining it; you still access and modify like a normal array:
std::vector<int> a;
a.push_back(2);
a.push_back(6);
std::cout << a[0] << std::end; //2
std::cout << a[1] << std::end; //6
a[0] = 5;
a[1] = 7;
std::cout << a[0] << std::end; //5
std::cout << a[1] << std::end; //7
You can also initialize it old-school style (the = is optional):
std::vector<int> a {2, 6};
std::cout << a[0] << std::end; //2
std::cout << a[1] << std::end; //6
Try this for C++:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec { 34,23 };
return 0;
}
Or even:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> v(2);
v = { 34,23 };
return 0;
}
seems non of the above gave you any hint on dealing with the vector after you created it, so, let's say you created it with few initial values.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec { 34,23 };
// use push_back(some_value) if you have multiple values to put inside, say 1000.
// instead of using the index [] brackets, try .at() method
std::cout << vec.at(1) << std::endl;
// use both the .size() or the new syntax to loop over it
for (unsigned i = 0 ; i < vec.size() ; i++){
std::cout << vec.at(i) << std::endl;
}
// or the new syntax
for (auto & i : vec){
std::cout << i << std::endl;
}
return 0;
}
Have fun :)
Vectors are expandable arrays. Unlike an array, you are not restricted to the size you initialized it with.
Growth of vector: the vector doubles it size whenever you overflow it. Underneath the hood its still an array but the "expandable" property of it comes by copying the contents of the previous array into a new larger array.
Few things that you can do with vectors in C++
Initialization of vector
vector<Type> one (size, defaultValue);
vector<Type> two (one); // makes a new vector *two* with the contents of *one*
vector<int> three {1,2,3}; // using initializer list
Accessing an element
int temp = three[2]; //array like syntax
int temp = three.at(2);
You cannot increase the size of a vector using this syntax i.e. you cannot dothree[3]=4;
Expanding
three.pusk_back(4);
Shrinking
three.pop_back();

How do you print a full array of values in C++

I'm trying to figure out print a full array in C++.
For example, I want the output to be x = [1,2,3,4,5....n]
How would I go about doing this? I already know how to print each element of the array using a simple for loop. For example in python, you could simply say x = [], make a for loop to append elements to the array, and print x.
So let's say I have this code.
int n = 10;
int m = 10;
double x[n];
// Generate vector of random values for x
for (int i = 0; i<n; ++i)
{
x[i] = (double)rand()/(double)RAND_MAX;
// Print each array element
// std::cout << x[i] << std::endl;
}
std::cout << x[n-1] << std::endl;
This obviously only spits out x[10] in this case. Where as I want x = [1...n] etc.
What is the simplest way of achieving this?
I'm using Eclipse on OSX. I use the g++ compiler that the Xcode developer tools has for the command line
You're looking for a range based for loop:
double x[] = { .0, .1, .2, .3, .4 };
// Iterate through all elements
for (auto d : x)
{
std::cout << d << std::endl;
}
Note that the above takes a copy of each element, so if you wanted to modify an element you'd need to use
for (auto& d : x)
instead.
Alternatively you could just use a normal for loop like you did originally:
for (int i = 0; i<n; ++i)
{
std::cout << x[i] << std::endl;
}
The range based for loop is the easiest though.
if you know something about STL , you can try to use iterator
code:
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
int arr[5] = {1,2,3,4,5};
copy(arr, arr + sizeof(arr)/sizeof(int),ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}

swap array values in c++

I want to shift left array values if my v=4 is in a[n],remove 4 from a[n] and at the end index add 0,how i can do this?
#include <iostream>
using namespace std;
const int n=5;
int main()
{
int a[n]={1,5,4,6,8}, v=4;
int b[n];
cout << "Enter a Value" << endl;
cout<<v<<endl;
for(int i=0; i<n; i++){
cout<<a[i];
}
cout<<endl;
for(int j=0; j<n; j++){
b[j]=a[j];
if(a[j]==v)
b[j]=a[++j];
cout<<b[j];
}
return 0;
}
#include <vector> // needed for vector
#include <algorithm> // needed for find
#include <iostream> // needed for cout, cin
using namespace std;
// Vectors are just like dynamic arrays, you can resize vectors on the fly
vector<int> a { 1,5,4,6,8 }; // Prepare required vector
int v;
cout << "enter value"; // Read from user
cin >> v;
auto itr = find( a.begin(), a.end(), v); // Search entire vector for 'v'
if( itr != a.end() ) // If value entered by user is found in vector
{
a.erase(itr); // Delete the element and shift everything after element
// Toward beginning of vector. This reduces vector size by 1
a.push_back(0); // Add 0 in the end. This increases vector size by 1
}
for( int i : a ) // Iterate through all element of a (i holds element)
cout << i; // Print i
cout << '\n'; // Line end
a few helpful links:
vector , find , iterator , erase , push_back
You could use std::rotate. I suggest that you use std::vector instead of C arrays and take full advantage of the STL algorithms. Nevertheless, below I'm illustrating two versions one with C arrays and one with std::vector:
Version with C array:
#include <iostream>
#include <algorithm>
int main()
{
int const n = 5;
int a[n] = {1,5,4,6,8};
std::cout << "Enter a Value" << std::endl;
int v;
std::cin >> v;
for(auto i : a) std::cout << i<< " ";
std::cout << std::endl;
auto it = std::find(std::begin(a), std::end(a), v);
if(it != std::end(a)) {
std::rotate(it + 1, it, std::end(a));
a[n - 1] = 0;
}
for(auto i : a) std::cout << i<< " ";
std::cout << std::endl;
return 0;
}
Version with vector:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> a{1,5,4,6,8};
std::cout << "Enter a Value" << std::endl;
int v;
std::cin >> v;
for(auto i : a) std::cout << i<< " ";
std::cout << std::endl;
auto it = std::find(std::begin(a), std::end(a), v);
if(it != std::end(a)) {
std::rotate(it + 1, it, std::end(a));
a.back() = 0;
}
for(auto i : a) std::cout << i<< " ";
std::cout << std::endl;
return 0;
}
Here's an example using std::array
#include <array>
#include <algorithm>
// defines our array.
std::array<int, 5> a = {{ 1, 2, 3, 4, 5 }};
// find the position of the element with the value 4.
auto where = std::find(a.begin(), a.end(), 4);
// if it wasn't found, give up
if (where == a.end())
return 0;
// move every element past "where" down one.
std::move(where + 1, a.end(), where);
// fill the very last element of the array with zero
a[ a.size() - 1] = 0;
// loop over our array, printing it to stdout
for (int i : a)
std::cout << i << " ";
std::cout << "\n";
Why would anyone use these awkward algorithms? Well, there are a few reasons. Firstly, they are container-independant. This will work with arrays and vectors and deques, no problem. Secondly, they can be easily used to work with a whole range of elements at once, not just single items, and can copy between containers and so on. They're also type-independant... you acn have an array of strings, or an vector of ints, or other more complex things, and the algorithms will still work just fine.
They're quite powerful, once you've got over their initial user-unfriendliness.
You can always use either std::array or std::vector or whatever without using the standard library algorithms, of course.
std::array<int, 5> a = {{ 1, 2, 3, 4, 5 }};
size_t where = 0;
int to_remove = 4;
// scan through until we find our value.
while (a[where] != to_remove && where < a.size())
where++;
// if we didn't find it, give up
if (where == a.size())
return 0;
// shuffle down the values
for (size_t i = where; i < a.size() - 1; i++)
a[i] = a[i + 1];
// set the last element to zero
a[ a.size() - 1] = 0;
As a final example, you can use memmove (as suggested by BLUEPIXY) to do the shuffling-down operation in one function call:
#include <cstring>
if (where < a.size() - 1)
memmove(&a[where], &a[where + 1], a.size() - where);