For any given n, I need to create a vector of vectors of length n std::vector<std::vector<int>>, containing all possible combinations of -1 and +1. For example, for n=3 I need
std::vector<std::vector<int>> v = {
{ 1, 1, 1},
{ 1, 1, -1},
{ 1, -1, 1},
{ 1, -1, -1},
{-1, 1, 1},
{-1, 1, -1},
{-1, -1, 1},
{-1, -1, -1}
};
Any hints?
Simple solution using the binary representation, and testing the bit value. I used std::bitset although you can also use the simple C-Style bit manipulations.
#include <bitset>
int main(){
int n=3;
int to = pow(2,n);
std::vector<std::vector<int>> result;
for (int i=0; i < to; i++){
std::bitset<32> b(i);
std::vector<int> vec1;
for (int j=0; j < n; j++){
int value = b.test(j) ? 1 : -1;
vec1.push_back(value);
}
result.push_back(vec1);
}
// Printing out result
for (auto& vec : result){
for (auto val : vec){
cout << val;
}
cout << endl;
}
}
Test Example
For larger values of (n), you might want to improve the efficiency:
std::vector<std::vector<int>> v;
v.reserve(1 << n);
for (unsigned int i = 0; i < (1 << n); i++)
{
std::vector<int> vi (n, 0);
for (unsigned int j = 0; j < n; j++)
vi[n - 1 - j] = (i & (1 << j)) ? (-1) : (+1);
v.push_back(vi);
}
I'm sure someone can come up with a template meta-program that can construct (v) at compile-time for a constant (n).
Following #sascha's suggestion, here's a method that appends +-1 to a given set of lists.
#include <vector>
#include <iostream>
std::vector<std::vector<int>>
append_plus_minus(const std::vector<std::vector<int>> & in)
{
auto out = in;
out.insert(out.end(), in.begin(), in.end());
for (std::size_t i=0; i < in.size(); i++) {
out[i].push_back(+1);
out[i+in.size()].push_back(-1);
}
return out;
}
int main() {
const int n = 5;
std::vector<std::vector<int>> b_combinations = {{}};
for (std::size_t i=0; i < n; i++) {
b_combinations = append_plus_minus(b_combinations);
}
for (std::size_t i=0; i < b_combinations.size(); i++) {
for (std::size_t j=0; j < b_combinations[i].size(); j++) {
std::cout << b_combinations[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}
Related
I want to create a nested array (v2) consisting of all elements from another array (arr) but grouped into two.
std::vector<std::vector<int> > v2;
int arr[8] = {0, 1, 2, 3, 4, 5, 6, 7};
//I want the v2 to be: {{0,1}, {2,3}, {4,5}, {6,7}}
std::cout << "v2.size = "<< v2.size() << '\n';
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 1; j++){
//I want the v2 to be: {{0,1}, {2,3}, {4,5}, {6,7}}
v2[i][j] = arr[2*i];
v2[i][j+1] = arr[2*i+1];
}
}
//No output...
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 2; j++) {
std::cout<<v2[i][j];
}
}
You need to reserve space in the vector before assigning to it using operator[]
Change
std::vector<std::vector<int>> v2;
to
std::vector<std::vector<int>> v2(4, std::vector<int>(2));
std::vector<std::pair<int, int> > v2;
int arr[8] = {0, 1, 2, 3, 4, 5, 6, 7};
//I want the v2 to be: {{0,1}, {2,3}, {4,5}, {6,7}}
std::cout << "v2.size = "<< v2.size() << '\n';
for (int i = 0; i < 4; i++) {
v2.push_back( std::pair<int, int>( arr[2*i], arr[2*i+1]) );
}
for (int i = 0; i < 4; i++) {
std::cout << v2[i].first << v2[i].second << std::endl;
}
I have 2 arrays:
arr1 = [0, 1, 2, 3, 4, 5, 6]
arr2 = [0, 1, 3, 3, 4, 6]
I'm trying to write a function to compare the two arrays and make a new array with the missing numbers.
I tried this for loop but it didn't print out anything. What other ways can I compare 2 arrays of different sizes?
int n = 0;
int *newArr = new int[];
for (int i = 0; i<=6; i++) {
if (arr1[i] != arr2[i]) {
newArr[n] = arr1[i]
n++;
}
}
for (int j = 0; j<n; j++) {
cout << arr[j] << endl;
}
I'm trying to write a function to compare the two arrays and make a
new array with the missing numbers.
You can use a range-based for loop and std::find to check both arrays for the missing numbers
And then store the result in a std::set
Example
int main()
{
int a[] { 0, 1, 2, 3, 4, 5, 6 };
int b[] { 0, 1, 3, 3, 4, 6 };
std::set<int> c;
for (auto const& i : a)
if (std::find(std::begin(b), std::end(b), i) == std::end(b))
c.insert(i);
for (auto const& i : b)
if (std::find(std::begin(a), std::end(a), i) == std::end(a))
c.insert(i);
}
or using a regular for loop
for (auto it = std::begin(a); it != std::end(a); ++it)
if (std::find(std::begin(b), std::end(b), *it) == std::end(b))
c.insert(*it);
Try something like this:
int arr1[] = {0, 1, 2, 3, 4, 5, 6};
int size_arr1 = 7;
int arr2[] = {0, 1, 3, 3, 4, 6};
int size_arr2 = 6;
int *newArr = new int[size_arr1 + size_arr2];
int n = 0;
for (int i = 0; i < size_arr1; i++) {
newArr[n++] = arr1[i];
}
for (int i = 0; i < size_arr2; i++) {
bool found = false;
for (int j = 0; j < n; j++) {
if (arr2[i] == newArr2[j]) {
found = true;
break;
}
}
if (!found)
newArr[n++] = arr1[i];
}
for (int i = 0; i < n; i++) {
cout << newArr[i] << endl;
}
delete[] newArr;
Another way to collect unique numbers from both arrays is to use a std::set or std::unsorted_set instead, eg:
#include <unordered_set>
int arr1[] = {0, 1, 2, 3, 4, 5, 6};
int arr2[] = {0, 1, 3, 3, 4, 6};
set::unsorted_set newArr;
for(int num : arr1) {
newArr.insert(num);
}
for(int num : arr2) {
newArr.insert(num);
}
for (int num : newArr) {
std:: cout << num << endl;
}
You've declared the arrays dynamically in your code (i.e. on the heap) and initializing them with numbers isn't as straight forward. You are also allocating an array of 0 size. If you declare your arrays on the stack then you can achieve what you want to do with a nested for loop.
Take note though that for large datasets this would be inefficient. If you're curious research binary search algorithms.
#include <iostream>
int main()
{
int arr1Size = 6;
int arr2Size = 8;
int arr1[] = { 2, 5, 7, 12, 45, 65 };
int arr2[] = { 2, 5, 6, 10, 32, 65, 98, 123 };
for (int i = 0; i < arr1Size; i++)
{
for (int j = 0; j < arr2Size; j++)
{
if (arr1[i] == arr2[j])
{
std::cout << arr1[i] << std::endl;
}
}
}
}
I'm trying to create a function to remove duplicates from an unsorted int array. I have a solution that works for more examples, but it's failing with the following input:
#include<iostream>
using namespace std;
int removeDuplicates(int arr[], int n)
{
int j = 0;
for (int i=0; i < n; i++){
for(int j=0;j<=i;j++){
if(arr[i]==arr[j]){
n--;
for (int k=i; k<n; k++){
arr[k]=arr[k+1];
}
}
}
}
return n;
}
// Driver code
int main()
{
int arr[] = {0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1};
int n = sizeof(arr) / sizeof(arr[0]);
n = removeDuplicates(arr, n);
for (int i=0; i<n; i++)
cout << arr[i] << " ";
return 0;
}
The output for this arr example is 0 0 1 0 0 and should be 0 1.
Do you see where is the problem? Thank you
Consider using std::set<int> to record numbers you've already seen, and using a STL algorithm to perform the removal:
#include<iostream>
#include<algorithm>
#include<functional>
#include<set>
// Driver code
int main()
{
int arr[] = {0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1};
std::set<int> duplicates;
auto it = std::remove_if(std::begin(arr), std::end(arr), [&duplicates](int i) {
return !duplicates.insert(i).second;
});
size_t n = std::distance(std::begin(arr), it);
for (size_t i = 0; i < n; i++)
std::cout << arr[i] << " ";
return 0;
}
The effect of this code is that all duplicates are moved to the end of the array, and the iterator returned by std::remove_if indicates the end of the new list. So iterating between the beginning and that iterator gives you the array without the duplicates.
look over inner loop you forgot to decrement i
#include<iostream>
using namespace std;
int removeDuplicates(int arr[], int n)
{
int j = 0;
for (int i=0; i < n; i++){
for(int j=0;j<i;j++){
if(arr[i]==arr[j]){
n--;
for (int k=i; k<n; k++){
arr[k]=arr[k+1];
}
i--; // you forgot to decrement i
}
}
}
return n;
}
// Driver code
int main()
{
int arr[] = {0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1};
int n = sizeof(arr) / sizeof(arr[0]);
n = removeDuplicates(arr, n);
for (int i=0; i<n; i++)
cout << arr[i] << " ";
return 0;
}
In your function
int removeDuplicates(int arr[], int n)
{
int j = 0;
for (int i=0; i < n; i++){
for(j=i+1;j<n;)
{
if(a[i]==a[j])
{
for(int k=j;k<n-1;++k)
arr[k]=arr[k+1];
--n;
}
else
++j;
}
}
return n;
}
Increment j only when the two values do not match. Or else it will skip few values
UPDATE
A possible solution that is O(n log n) in time and requires O(m) extra space, where m is the number of unique elements in the input array:
template <typename RAIter>
size_t remove_duplicates(RAIter first, RAIter last) {
using value_type = typename std::iterator_traits<RAIter>::value_type;
std::map<value_type, size_t> map;
size_t n = 0;
for (auto it = first; it != last; ++it) {
auto & temp = map[*it];
if (temp == 0) temp = ++n;
}
for (auto & e : map)
*(first + e.second - 1) = e.first;
return n;
}
Note also that the contents of the original array is destroyed here, but this is in your attempt as well.
Possible usage:
int main() {
static constexpr size_t n = 26;
std::array<int, n> a = { 0, 0, 1, 0, 3, 2, 1, 1, 0, 1, 0, 0, 2, 2, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1 };
size_t m = remove_duplicates(std::begin(a), std::end(a));
for (size_t i = 0; i < m; i++)
std::cout << a[i] << " ";
std::cout << std::endl;
}
Which prints out 0 1 3 2.
I compared my solution with yours (corrected by #Onk_r). For an input array of 500,000 elements having random values from [0,100). My O(n log n) solution took 19 milliseconds, while your O(n3) solution took 54 seconds! Nice demonstration of how much complexity matters :).
It works, but you have to start with j=1, not 0
wrong:
for (int i=0; i < n; i++){
for(int j=0;j<=i;j++)
solution:
for (int i=0; i < n; i++){
for(int j=1;j<=i;j++){
int arr1[] = {3, 1, 5, 4, 5, 1, 9, 3, 9, 7};
int size = sizeof(arr1) / sizeof(arr1[0]);
int i, j, k = 0;
int arr2[size];
for(i = 0; i < size; i++)
{
for(j = 0; j < k; j++)
{
if(arr1[i] == arr2[j])
{
break;
}
}
if(j == k)
{
arr2[k++] = arr1[i];
}
}
Use a set instead since all elements in a set must be unique. http://www.cplusplus.com/reference/set/set/
I know using vectors is much easier but it just crossed my mind if i wanted to use C-style arrays to do generic matrix multiplication, how would that work. I searched online and got some help by using templates but the array won't return from the function.
// Example program
#include <iostream>
#include <string>
using namespace std;
template <typename T, size_t row1, size_t col1, size_t row2, size_t col2>
typename multiply(T(&a)[row1][col1], T(&b)[row2][col2]) {
if (row1 != col2) {
cout << "Error! Rows of first matrix is not the same as Columns of second "
"matrix, therefore Multiplication is NOT POSSIBLE!";
return 0;
} else {
T c[row1][col2];
for (size_t i = 0; i < row1; ++i) {
for (size_t j = 0; j < col2; ++j) {
c[i][j] = 0;
for (size_t k = 0; k < col1; ++k) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
}
int main() {
// C-style array
int my_array[2][5] = {{1, 2, 3, 4, 5}, {1, 2, 3, 4, 5}};
int my_array2[5][2] = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}};
int my_array3[2][2];
int c[2][2] = multiply(my_array, my_array2);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
cout << c[i][j] << " ";
}
cout << endl;
}
return 0;
}
So any idea how I can make this code work?
You can't either return 0 either return c in your function as you do.
Instead, pass the output as a parameter c and put a and b as const.
The return of the function is the error code (0 for OK, -1 for KO)
Btw, your check condition is wrong, I corrected it also
// Example program
#include <iostream>
#include <string>
using namespace std;
template <typename T, size_t row1, size_t col1, size_t row2, size_t col2>
int multiply(const T(&a)[row1][col1], const T(&b)[row2][col2], T(&c)[row1][col2] ) {
if (col1 != row2) {
cout << "Error! Columns of first matrix is not the same as Rows of second "
"matrix, therefore Multiplication is NOT POSSIBLE!";
return -1;
} else {
//T c[row1][col2];
for (size_t i = 0; i < row1; ++i) {
for (size_t j = 0; j < col2; ++j) {
c[i][j] = 0;
for (size_t k = 0; k < col1; ++k) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return 0;
}
}
int main() {
// C-style array
int my_array[2][5] = {{1, 2, 3, 4, 5}, {1, 2, 3, 4, 5}};
int my_array2[5][2] = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}};
int my_array3[2][2];
int a = multiply(my_array, my_array2,my_array3);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
cout << my_array3[i][j] << " ";
}
cout << endl;
}
return 0;
}
You can pass the result as a parameter:
template<class T,int NLine1,int NC1L2,int NCol2>
void multiply(T (left&)[NLine1][NC1L2], T(right&)[NC1L2][NCol2], T(result&)[NLine1][NCol2]);
How to input array here? i.e the user has to give the 5 values for arr[] instead of arr[] = (0, -1, 2, -3, 4} . If I give arr[] it shows error. I'm a begginer so please help me.
using namespace std; // function to print triplets with 0 sum
void findTriplets(int arr[], int n)
{
bool found = false;
for (int i=0; i<n-1; i++)
{
// Find all pairs with sum equals to
// "-arr[i]"
unordered_set<int> s;
for (int j=i+1; j<n; j++)
{
int x = -(arr[i] + arr[j]);
if (s.find(x) != s.end())
{
printf("%d %d %d\n", x, arr[i], arr[j]);
found = true;
}
else
s.insert(arr[j]);
}
}
if (found == false)
cout << " No Triplet Found" << endl; }
int main()
{
int arr[] = {0, -1, 2, -3, 1};
int n = sizeof(arr)/sizeof(arr[0]);
findTriplets(arr, n);
return 0; }
The simplest way is to get n from user and cin arr in a loop:
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; ++i) {
cin >> arr[i];
}
findTriplets(arr, n);
If you don't want to pass the size of array you can use std::vector instead of array, and the push_back() method;