I set a vector list, for example :
vector<VectorXi> Test;
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2));
Test.push_back(VectorXi(0));
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2,3));
PrintAllCombins(Test)
And now I want to get all combinations of indexes :
0, 0, 0, 0, 0
0, 0, 0, 0, 1
0, 0, 0, 0, 2
0, 0, 0, 0, 3
0, 0, 0, 1, 0
0, 0, 0, 1, 1
0, 0, 0, 1, 2
0, 0, 0, 1, 3
0, 0, 1, 0, 0
0, 0, 1, 0, 1
0, 0, 1, 0, 2
0, 0, 1, 0, 3
... and so on
If i use for or while loop suitably, then it works I guess, but I encounter limitation. Is there any idea? I'm writing code in c and c++
--------------------- code : this is an example code that im using.
vector<VectorXi> Test;
VectorXi a0(2); a0[0] = 0; a0[1] = 1;
VectorXi a1(3); a1[0] = 0; a1[1] = 1; a1[2] = 2;
VectorXi a2(2); a2[0] = 0; a2[1] = 1;
VectorXi a3(4); a3[0] = 0; a3[1] = 1; a3[2] = 2; a3[3] = 3;
VectorXi a5(1); a5[0] = 0;
Test.push_back(a0);
Test.push_back(a1);
Test.push_back(a5);
Test.push_back(a2);
Test.push_back(a3);
VectorXi index(5);
for (int i = 0; i < 5; i++)
index[i] = 0;
int IndexTemp = Test.size()-1;
vector<VectorXi> result;
bool c = true;
while (c == true)
{
if (index[IndexTemp] < Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
index[IndexTemp] ++;
}
else if (index[IndexTemp] == Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
IndexTemp--;
if (IndexTemp < 0)
break;
index[IndexTemp] ++;
}
}
for (unsigned int i = 0; i < result.size(); i++)
{
cout << i << " : ";
for (unsigned int j = 0; j < result[i].size(); j++)
{
cout << result[i](j) << " ";
}
cout << endl;
}
It does not show all combinations now..
If I make code to work only to this example (Test.size() == 5)
I just use for loop five times like :
for(Test[0].size())
for(Test[1].size())
for(Test[2].size())
for(Test[3].size())
for(Test[4].size())
cout << ~~~~~
Then it gives all combinations.
However if the Test.size() increased, I cannot write all for loops manually.
You may do:
bool increase(const std::vector<std::vector<int>>& v, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] >= v[index].size()) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void do_job(const std::vector<std::vector<int>>& v,
const std::vector<std::size_t>& it)
{
for (std::size_t i = 0; i != it.size(); ++i) {
// TODO: manage case where v[i] is empty if relevant.
std::cout << v[i][it[i]] << " ";
}
std::cout << std::endl;
}
void iterate(const std::vector<std::vector<int>>& v)
{
std::vector<std::size_t> it(v.size(), 0u);
do {
do_job(v, it);
} while (increase(v, it));
}
Live Demo
Related
I set a vector list, for example :
vector<VectorXi> Test;
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2));
Test.push_back(VectorXi(0));
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2,3));
PrintAllCombins(Test)
And now I want to get all combinations of indexes :
0, 0, 0, 0, 0
0, 0, 0, 0, 1
0, 0, 0, 0, 2
0, 0, 0, 0, 3
0, 0, 0, 1, 0
0, 0, 0, 1, 1
0, 0, 0, 1, 2
0, 0, 0, 1, 3
0, 0, 1, 0, 0
0, 0, 1, 0, 1
0, 0, 1, 0, 2
0, 0, 1, 0, 3
... and so on
If i use for or while loop suitably, then it works I guess, but I encounter limitation. Is there any idea? I'm writing code in c and c++
--------------------- code : this is an example code that im using.
vector<VectorXi> Test;
VectorXi a0(2); a0[0] = 0; a0[1] = 1;
VectorXi a1(3); a1[0] = 0; a1[1] = 1; a1[2] = 2;
VectorXi a2(2); a2[0] = 0; a2[1] = 1;
VectorXi a3(4); a3[0] = 0; a3[1] = 1; a3[2] = 2; a3[3] = 3;
VectorXi a5(1); a5[0] = 0;
Test.push_back(a0);
Test.push_back(a1);
Test.push_back(a5);
Test.push_back(a2);
Test.push_back(a3);
VectorXi index(5);
for (int i = 0; i < 5; i++)
index[i] = 0;
int IndexTemp = Test.size()-1;
vector<VectorXi> result;
bool c = true;
while (c == true)
{
if (index[IndexTemp] < Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
index[IndexTemp] ++;
}
else if (index[IndexTemp] == Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
IndexTemp--;
if (IndexTemp < 0)
break;
index[IndexTemp] ++;
}
}
for (unsigned int i = 0; i < result.size(); i++)
{
cout << i << " : ";
for (unsigned int j = 0; j < result[i].size(); j++)
{
cout << result[i](j) << " ";
}
cout << endl;
}
It does not show all combinations now..
If I make code to work only to this example (Test.size() == 5)
I just use for loop five times like :
for(Test[0].size())
for(Test[1].size())
for(Test[2].size())
for(Test[3].size())
for(Test[4].size())
cout << ~~~~~
Then it gives all combinations.
However if the Test.size() increased, I cannot write all for loops manually.
You may do:
bool increase(const std::vector<std::vector<int>>& v, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] >= v[index].size()) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void do_job(const std::vector<std::vector<int>>& v,
const std::vector<std::size_t>& it)
{
for (std::size_t i = 0; i != it.size(); ++i) {
// TODO: manage case where v[i] is empty if relevant.
std::cout << v[i][it[i]] << " ";
}
std::cout << std::endl;
}
void iterate(const std::vector<std::vector<int>>& v)
{
std::vector<std::size_t> it(v.size(), 0u);
do {
do_job(v, it);
} while (increase(v, it));
}
Live Demo
I am working on a matrix inverter and I have it almost done but for some reason the function that is supposed to raise the matrix to a certain value is not working, I have isolated the function on its own and it has worked just fine. But for some reason is not working in this program
Isolated
#include <iomanip>
#include <stdio.h>
using namespace std;
void printano(double a[3][3])
{
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
cout << fixed << setprecision(2) << setw(12) << a[i][j] << " ";
cout << endl;
}
}
void powernator(double r[][3],double B[][3], int p)
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
int main()
{
double B[3][3] = { {1, 2, 3} , {4, 5, 6} , {7, 8, 9} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
powernator(r,B,3);
printano(r);
}
The actual code
#include <iostream>
#include <iomanip>
#include <cmath>
#include <stdio.h>
using namespace std;
void multiplinator(double x[][3], double y[][3], double z[][3]) //At the end I double check to make sure the value is correct as it needs to equal the identity matrix
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 3; k++)
{
z[i][j] += x[i][k] * y[k][j];
}
}
}
}
void printinator(double a[3][3]) //prints a matrix
{
for(int i=0; i<=2; i++)
{
for(int j=0; j<=2; j++)
cout << fixed << setprecision(4) << setw(12) << a[i][j] << " ";
cout << endl;
}
cout << endl;
}
void sub(double as[3][3], double in[][3], double B[][3]) //Matrix subtraction
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
B[i][j] = in[i][j] - as[i][j];
}
void powernator(double r[][3],double B[][3], int p) //Array which is supposed to raise a matrix to a certain power
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
void gettem(double r[][3], double in[][3], double inm[][3]) //Supposed to return the final value, aka, the inverse matrix, as a^-1 = I + B^1 +B^2...
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
inm[i][j] = in[i][j] + r[i][j];
}
}
int main()
{
double a[3][3] = { {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double as[3][3] ={ {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double in[3][3] = { {1, 0, 0} , {0, 1, 0} , {0, 0, 1} };
double B[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double inm[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double z[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
cout << "\n\t\t Original : " << endl;
printinator(a);
sub(as,in,B);
printinator(B);
powernator(r,B,2);
printinator(r); //testing the power function, not working
/*for(int n = 0; n < 20; n++) //Final part of the code commented out for debug, this loop is meant to add up B^n where n is from 1 - 20
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
r[i][j] += B[i][j];
}
gettem(r,in,inm);
cout << "\n\t\t Inverse: " << endl;
printinator(inm);
multiplinator(as,a,z);
cout << "\n\t\t multi: " << endl;
printinator(z);
*/
}
Isolated Code
powernator(r,B,3);
Actual Code.
powernator(r,B,2);
parameter p is differ..
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/
char ToByte(bool b[8])
{
char c = 0;
int j = 0;
for (int i = 7; i >= 0; i--) {
if (b[j]) {
c |= 1 << i;
}
j++;
}
return c;
}
This function converts from bool to char
int main() {
int number = 979899101;
bitset<32> byte4= number;
cout << byte4 << endl;;
bitset<8> byte;
char op[4];
for (int i = 3; i >= 0; i--) {
for (int j = 0; j < 8; ++j)
byte[j] = byte4[i * 8 + j];
cout << byte;
bool var[8];
for (int j = 0; j < 7; ++j)
var[j] = byte[j];
op[i]=ToByte(var);
}
cout << op;
}
I'm trying to get convertion from integer to char array but I'm getting bad result. like ╗I↨]╠╠╠╠╠╠╠╠Ţ I don't know what I'm doing wrong.
Your function that converts bool array to char works correctly.
Try this:
bool a[] = {0, 1, 1, 0, 0, 0, 0, 1}; //97
bool b[] = {0, 1, 1, 0, 0, 0, 1, 0}; //98
bool c[] = {0, 1, 1, 0, 0, 0, 1, 1}; //99
bool d[] = {0, 1, 1, 0, 0, 1, 0, 0}; //100
cout << ToByte(a) << ToByte(b) << ToByte(c) << ToByte(d) << endl;
So you need to decide, how to split big number (979899101) into pieces (bitset<8> byte), because your code in main() do is not what you expect.
It splits the long number 00111010011010000001001011011101 into 58(00111010), 104(01101000), 18(00010010) and 221(11011101)
off topic: sorry for my broken English, this isn't my native language.
For knight tour problem, I came up with this answer; however, it just prints one answer. I don't know how to print all answers. I know I should change the output of find tour into void to avoid finishing but I don't know how. Can anyone modify it?
#include <iostream>
using namespace std;
const int ROW_COUNT = 6;
const int COL_COUNT = 6;
const int POSSIBLE_MOVES = 8;
int row_delta[POSSIBLE_MOVES] = {2, 1, -1, -2, -2, -1, 1, 2};
int col_delta[POSSIBLE_MOVES] = {-1, -2, -2, -1, 1, 2, 2, 1};
int board[ROW_COUNT][COL_COUNT];
void print_board() {
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COL_COUNT; j++) {
if (board[i][j] < 10)
cout << ' ';
cout << board[i][j] << ' ';
}
cout << endl;
}
cin.get();
}
bool find_tour(int move_no, int current_row, int current_col) {
// uncomment the following two lines for debugging:
//cout << move_no << endl;
//print_board();
if (move_no == ROW_COUNT * COL_COUNT)
return true;
for (int move = 0; move < POSSIBLE_MOVES; move++) {
int new_row = current_row + row_delta[move];
int new_col = current_col + col_delta[move];
if (new_row < 0 || new_row >= ROW_COUNT || new_col < 0 || new_col >= COL_COUNT)
continue;
if (board[new_row][new_col] != 0)
continue;
board[new_row][new_col] = move_no + 1;
if (find_tour(move_no + 1, new_row, new_col))
return true;
board[new_row][new_col] = 0;
}
return false;
}
void solve(int init_row, int init_col) {
for (int row = 0; row < ROW_COUNT; row++)
for (int col = 0; col < COL_COUNT; col++)
board[row][col] = 0;
board[init_row][init_col] = 1;
if (find_tour(1, init_row, init_col))
print_board();
else
cout << "Failed to find a tour!\n";
}
int main() {
solve(2, 3);
}
Following from my comment, this code should work:
#include <iostream>
using namespace std;
const int ROW_COUNT = 6;
const int COL_COUNT = 6;
const int POSSIBLE_MOVES = 8;
int row_delta[POSSIBLE_MOVES] = {2, 1, -1, -2, -2, -1, 1, 2};
int col_delta[POSSIBLE_MOVES] = {-1, -2, -2, -1, 1, 2, 2, 1};
int board[ROW_COUNT][COL_COUNT];
void print_board() {
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COL_COUNT; j++) {
if (board[i][j] < 10)
cout << ' ';
cout << board[i][j] << ' ';
}
cout << endl;
}
cin.get();
}
find_tour(int move_no, int current_row, int current_col) {
// uncomment the following two lines for debugging:
//cout << move_no << endl;
//print_board();
if (move_no == ROW_COUNT * COL_COUNT)
{
print_board();
return;
}
for (int move = 0; move < POSSIBLE_MOVES; move++) {
int new_row = current_row + row_delta[move];
int new_col = current_col + col_delta[move];
if (new_row < 0 || new_row >= ROW_COUNT || new_col < 0 || new_col >= COL_COUNT)
continue;
if (board[new_row][new_col] != 0)
continue;
board[new_row][new_col] = move_no + 1;
find_tour(move_no + 1, new_row, new_col);
board[new_row][new_col] = 0;
}
}
void solve(int init_row, int init_col) {
for (int row = 0; row < ROW_COUNT; row++)
for (int col = 0; col < COL_COUNT; col++)
board[row][col] = 0;
board[init_row][init_col] = 1;
find_tour(1, init_row, init_col);
}
int main() {
solve(2, 3);
}