Related
I am trying to find unique element from the array these is question
Input : arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5}
Output : arr[] = {1, 2, 3, 4, 5}
They give me correct output but why they give 0 at the end in output:
these is my output:
{1,2,3,4,5,0}
Code:
#include<iostream>
using namespace std;
int main(){
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0;j<=n;j++){
if(arr[j]!=arr[j+1]){
cout<<arr[j];
}
}
}
Except for std::cout, you code is much more C than ++.
std::unique of the C++ Standard Library does exactly what you want. There is no need to re-implement this.
Next there is the erase-remove idiom to delete the superfluous elements.
For the output, you can use std::for_each() or at least a range-based for loop.
And also, you don't want using namespace std;
A more modern solution looks like this:
#include <iostream>
#include <algorithm>
#include <vector>
int main(){
std::vector<int> arr {1, 2, 2, 3, 4, 4, 4, 5, 5};
auto last = std::unique(arr.begin(), arr.end());
arr.erase(last, arr.end());
std::for_each(arr.begin(), arr.end(), [](int n){std::cout << n << std::endl;} );
}
Try it on Godbolt.
problem is in for loop becouse you use less or equal to n.
you need to use just less then n becouse array starts from zero that means you asking for sixth element that do not have alocalizated in memory
now it should be correct
#include<iostream>
using namespace std;
int main() {
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0; j<n; j++) {
if (arr[j]!=arr[j+1]) {
cout<<arr[j];
}
}
}
I am trying to sort a c++ subarray by first element.
My code is currently set up like this:
int umbrellas[3][2] = {{5, 6}, {2, 7}, {9, 20}};
int n = sizeof(umbrellas) / sizeof(umbrellas[0]);
sort(umbrellas, umbrellas + n, greater<int>());
The sort function doesn't seem to be functioning properly and when I run the code it generates errors. Is there a way to sort the array from
{{5, 6}, {2, 7}, {9, 20}}
into
{{2, 7}, {5, 6}, {9, 20}}
?
Use a std::vector of std::vector as your container and the sort becomes much easier to do with. Not only is std::vector the preferred container for C++ but using STL functions on it is way simpler and direct , without any substantiable overhead.
Define your data as
std::vector<std::vector<int>> umbrellas{
{5, 6},
{2, 7},
{9, 20}
};
Now you can use a custom comparator lambda that takes in two vector element references and returns True when the first element of the above vector is smaller than that of the one below.
std::sort(umbrellas.begin(),
umbrellas.end(),
[](const std::vector<int> &above, const std::vector<int> &below)
{
return (above[0] < below[0]);
});
And the output :
for (auto &&row : umbrellas) {
for (auto element : row) {
std::cout<< element<< " ";
}
std::cout<< "\n";
}
2 7
5 6
9 20
Taking this to C++20 it's even easier:
std::ranges::sort(umbrellas, std::less(),
[](const auto &v) { return v[0];});
If time complexity doesn't matter, this code will achieve the desired with O(n^2) complexity
int arr[3][2] = {{5, 6}, {2, 7}, {9, 20}};
int n = sizeof(arr) / sizeof(arr[0]);
for(int i = 0 ; i < n - 1; i++){
for(int j = 0 ; j < n - 1 ; j++){
if(arr[j][0] > arr[j + 1][0])
swap(arr[j],arr[j + 1]);
}
}
I have following vectors:
std::vector<A*> vec;
std::vector<std::pair<A*, A*>> vec_pair;
vec_pair size is much more than vec size. I would like to find a pair within vec_pair which both members are inside vec.
contents of the vec_pair are constant. However after each iteration the contents of the vec will change and I would like to do the test again.
I know I can do a for loop and do the check. However considering size difference and recurrence of the job, I am looking for a smart and efficient way to do it.
If you are not going to change content of vec, create an std::unordered_set<A*> with the same content and search for occurrences there. Searching in an unordered_set is approximately O(1), so this would be a simple win.
The easiest and the most efficient way to construct an unordered_set from a vector is to use the constructor taking two iterators:
unordered_set<A*> us(vec.begin(), vec.end());
You can use an unordered_set (you don't really need a map) which allows O(1) search and insert.
1) From vec you build an unordered_set<A*> S;
2) For each pair in vec_pair you can check if both elements are present in S
Something like the following will do the job in average O(vec_pair.size())
std::vector<A*> vec;
std::vector<std::pair<A*, A*>> vec_pair;
unordered_set<A*> S;
for(auto a: vec)
S.insert(a);
for(auto p : vec_pair){
if(s.find(p.first)!=S.end() &&
s.find(p.second)!=S.end())
{
//PAIR GOOD
}else{
//THIS PAIR IS NOT GOOD
}
}
vec_pair size is much more than vec size.
This should act as a clue to you to use std::map.
Put all the elements of vector vec inside a map : myMap[vec[i]] = 1;
Then go through each pair in vec_pair, and do
if (myMap.find(vec_pair[i].first != myMap.end()) &&
myMap.find(vec_pair[i].second != myMap.end()) )
{
return FOUND;
}
else
return NOT_FOUND;`
As commented by Gates, use unordered_map for faster operations.
I don't know yours exactly requirements but, if the order of element in vec_pair isn't important, I suppose you can substitute it with a std::multimap or, I suppose better, a std::unordered_multimap.
I mean (using a type A equal to int as example) that instead
using A = int;
std::vector<std::pair<A, A>> const vec_pair
{ {1, 1}, {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 2}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 3}, {3, 4},
{4, 1}, {4, 2}, {4, 3}, {4, 4} };
you can use
std::unordered_multimap<A, A> const cM
{ {1, 1}, {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 2}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 3}, {3, 4},
{4, 1}, {4, 2}, {4, 3}, {4, 4} };
If you need that vec_pair is a vector of pairs, using the fact that vec_pair is constant (I understand correctly?) you can contruct a constant unordered multimap.
The advantage of this solution is that if you find that a key of the map isn't in vec, you can avoid the test for all the values with the same key.
More: if construct a set (or, better, an unordered_set) starting from vec (that is little, if I understand correctly, you can check the pairs as follows
for ( auto ci = cM.cbegin() ; ci != cM.cend() ; )
{
auto val = ci->first;
auto cnt = cM.count(val);
if ( s.end() == s.find(val) )
{
for ( auto i = 0U ; i < cnt ; ++i )
++ci;
}
else for ( auto i = 0U ; i < cnt ; ++i, ++ci )
if ( s.end() != s.find(ci->second) )
std::cout << "- good for <" << val << ", " << ci->second
<< '>' << std::endl;
}
I know: isn't an elegant solution.
Another way is to use a combination of map and set (unorderd, better) and instead of
std::vector<std::pair<A, A>> const vec_pair
{ {1, 1}, {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 2}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 3}, {3, 4},
{4, 1}, {4, 2}, {4, 3}, {4, 4} };
use (or construct)
std::unordered_map<A, std::unordered_set<A>> const cM
{ {1, {1, 2, 3, 4}}, {2, {1, 2, 3, 4}},
{3, {1, 2, 3, 4}}, {4, {1, 2, 3, 4}} };
In this case, the search part is more elegant (IMHO)
for ( auto const & p : cM2 )
if ( s.end() != s.find(p.first) )
for ( auto const & sec : p.second )
if ( s.end() != s.find(sec) )
std::cout << "- good for <" << p.first << ", " << sec
<< '>' << std::endl;
The following is a full compilable example for both solutions
#include <vector>
#include <utility>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
int main()
{
using A = int;
std::unordered_multimap<A, A> const cM
{ {1, 1}, {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 2}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 3}, {3, 4},
{4, 1}, {4, 2}, {4, 3}, {4, 4} };
std::unordered_set<A> s { 4, 3 };
for ( auto ci = cM.cbegin() ; ci != cM.cend() ; )
{
auto val = ci->first;
auto cnt = cM.count(val);
if ( s.end() == s.find(val) )
{
for ( auto i = 0U ; i < cnt ; ++i )
++ci;
}
else for ( auto i = 0U ; i < cnt ; ++i, ++ci )
if ( s.end() != s.find(ci->second) )
std::cout << "- good for <" << val << ", " << ci->second
<< '>' << std::endl;
}
std::unordered_map<A, std::unordered_set<A>> const cM2
{ {1, {1, 2, 3, 4}}, {2, {1, 2, 3, 4}},
{3, {1, 2, 3, 4}}, {4, {1, 2, 3, 4}} };
for ( auto const & p : cM2 )
if ( s.end() != s.find(p.first) )
for ( auto const & sec : p.second )
if ( s.end() != s.find(sec) )
std::cout << "- good for <" << p.first << ", " << sec
<< '>' << std::endl;
}
How much smaller is vec than vec_pair? Is the square of the size of vec still much smaller than the size of vec_pair? If so, you make an unordered_set out of vec_pair, and then search it for every possible pair generated from two things from vec.
Why can't you sort the two containers? Can you make a sorted copy of each? If so, take a pointer to the start of both lists, and increment both looking for matches. You would still be O(size of vec_pair) but your constant would be really small -- often just a single pointer comparison.
My target is to insert vector in another vector from specific position with c++.
Example:
std::vector<int> a = {1, 2, 3};
std::vector<int> b = {4, 5, 6};
int position = 1;
Output: 1, 4, 5, 6, 2, 3.
It's easy:
vector<int> a = {1, 2, 3};
vector<int> b = {4, 5, 6};
int position = 1;
a.insert(a.begin()+position,b.begin(),b.end());
We can easily do it by insert function.
std::vector<int> a = {1, 2, 3};
std::vector<int> b = {4, 5, 6};
auto it = a.begin();
int position = 1;
a.insert(it+position, b.begin(), b.end());
I want to pass an array to a constructor, but only the first value is passed--the rest looks like garbage.
Here's a simplified version of what I'm working on:
#include <iostream>
class board
{
public:
int state[64];
board(int arr[])
{
*state = *arr;
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << state[x + y*8] << " ";
std::cout << "\n";
}
}
int main()
{
int test[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
board b(test);
b.print();
std::cin.get();
return 0;
}
Can someone explain why this doesn't work and how to properly pass an array? Also, I don't want to copy the array. (And do I really have to indent every line by 4 spaces for code? That's pretty tedious.)
In this case it might be best to use a reference to the array:
class board
{
int (&state)[64];
public:
board(int (&arr)[64])
: state(arr)
{}
// initialize use a pointer to an array
board(int (*p)[64])
: state(*p)
{}
void print();
};
A couple of advantages - no copying of the array, and the compiler will enforce that the correct size array is passed in.
The drawbacks are that the array you initialize the board object with needs to live at least as long as the object and any changes made to the array outside of the object are 'reflected' into the object's state. but those drawbacks occur if you use a pointer to the original array as well (basically, only copying the array will eliminate those drawbacks).
One additional drawback is that you can't create the object using a pointer to an array element (which is what array function parameters 'decay' to if the array size isn't provided in the parameter's declaration). For example, if the array is passed through a function parameter that's really a pointer, and you want that function to be able to create a board object referring to that array.
Attempting to pass an array to a function results in passing a pointer to the first element of the array.
You can't assign arrays, and taking a parameter like T[] is the same as T*. So
*state = *arr;
Is dereferencing the pointers to state and arr and assigning the first element of arr to the first element of state.
If what you want to do is copy the values from one array to another, you can use std::copy:
std::copy(arr, arr + 64, state); // this assumes that the array size will
// ALWAYS be 64
Alternatively, you should look at std::array<int>, which behaves exactly like you were assuming arrays behave:
#include <array>
#include <algorithm>
#include <iostream>
class board
{
public:
std::array<int, 64> state;
board(const std::array<int, 64> arr) // or initialiser list : state(arr)
{
state = arr; // we can assign std::arrays
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << state[x + y*8] << " ";
std::cout << "\n";
}
}
int main()
{
// using this array to initialise the std::array 'test' below
int arr[] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
std::array<int, 64> test(std::begin(arr), std::end(arr));
board b(test);
b.print();
std::cin.get();
return 0;
}
#include <iostream>
class board
{
public:
int * state; //changed here, you can also use **state
board(int *arr) //changed here
{
state = arr;
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << *(state + x + y*8) << " "; //changed here
std::cout << "\n";
}
}
int main()
{
int test[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
board b(test);
b.print();
std::cin.get();
return 0;
}
or you can use it as:
class board
{
public:
int state[64];
board(int arr[])
{
for(int i=0;i<64;++i)
state[i] = arr[i];
}
void print();
};
EDIT 1:
stable solution
class board
{
public:
int * state; //changed here, you can also use **state
board(int *arr) //changed here
{
state = new int[64];
for(int i=0;i<64;++i)
state[i] = arr[i];
}
void print();
};
*arr gives the value that is stored at arr[0] . In c++ , the name of the array is a pointer to the first element in the array.
So when you do *state = *arr , you store the value at arr[0] in the variable state.
Now , if you want to pass the array without having to copy each element explicitly , I suggest that you make another array of the same size in the method which you are calling and then pass the name of the array from the caller , in essence :
methodWhereArrayisPassed(int *arrayName)
{
int arrCopy[64];
arrCopy = arrayName;
// Do more stuff here
}
methodWhichPassesArray()
{
// do stuff here
int arr[] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
methodWhereArrayisPassed(arr);
// do stuff here
}
The name of an array is the address of the first element in it.
Hence the line *state = *arr will set state[0] to arr[0].
Since right now you have defined state as int state[64];, state is const pointer of type int whose address cannot be changed.
You can change it to int *state; and then state = arr will work.
*state = *arr; is using dereferencing, which returns the value at the address of the pointer.
This is the same as state[0] = *arr; because *arr is an int.
See this article for info on pointers. See the deference section.
To solve this problem you want to do this:
for (int i = 0; i < 64; i++) state[i] = arr[i]