Help me please.
I have a 3d vector. I need to make a new vector from this using existing internal indices. I hope the input and output information will be clear.
Input:
a = {
{ {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} },
{ {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} },
{ {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} },
};
Output:
b = {
{{ 1,1,1,1}, {10,10,10,10}, {100,100,100,100}},
{{ 2,2,2,2}, {20,20,20,20}, {200,200,200,200}},
{{ 3,3,3,3}, {30,30,30,30}, {300,300,300,300}},
{{ 4,4,4,4}, {40,40,40,40}, {400,400,400,400}},
{{ 5,5,5,5}, {50,50,50,50}, {500,500,500,500}},
{{ 6,6,6,6}, {60,60,60,60}, {600,600,600,600}},
}
I don't know how to iterate over indices in a 3D array to create a new 3D array (Output). I want to create a 3D vector from the columns (n-indices) of an existing 3D vector. I have a 3D vector ('Input'). I need to make a 3D vector out of this ('Output').
#include <iostream>
#include <vector>
using namespace std;
void show3D_vector(std::vector<std::vector<std::vector<double>>>& a);
void show2D_vector(std::vector<std::vector<double>>& a);
template<typename T> std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n);
int main()
{
a = {
{ {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} },
{ {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} },
{ {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} },
};
}
void show3D_vector(std::vector<std::vector<std::vector<double>>>& a)
{
for (double i = 0; i < a.size(); ++i)
{
for (double j = 0; j < a[i].size(); ++j)
{
for (double k = 0; k < a[i][j].size(); ++k)
std::cout << a[i][j][k] << " ";
std::cout << endl;
}
std::cout << endl;
}
}
void show2D_vector(std::vector<std::vector<double>>& a)
{
for (int i = 0; i < a.size(); i++) {
for (auto it = a[i].begin(); it != a[i].end(); it++)
{
std::cout << *it << " ";
}
std::cout << endl << endl;
}
}
template<typename T>
std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n)
{
std::vector<std::vector<T>> outVec;
size_t length = vec.size() / n;
size_t remain = vec.size() % n;
size_t begin = 0;
size_t end = 0;
for (size_t i = 0; i < std::min(n, vec.size()); ++i)
{
end += (remain > 0) ? (length + !!(remain--)) : length;
outVec.push_back(std::vector<T>(vec.begin() + begin, vec.begin() + end));
begin = end;
}
return outVec;
}
Thank you.
You can solve this matrix transpose more succinctly.
for(const auto& a1 : a){
b.resize(a1.size());
auto b1 = b.begin();
for(const auto& a2 : a1){
b1->push_back(a2);
b1++;
}
}
output is
{{1,1,1,1,},{10,10,10,10,},{100,100,100,100,},},
{{2,2,2,2,},{20,20,20,20,},{200,200,200,200,},},
{{3,3,3,3,},{30,30,30,30,},{300,300,300,300,},},
{{4,4,4,4,},{40,40,40,40,},{400,400,400,400,},},
{{5,5,5,5,},{50,50,50,50,},{500,500,500,500,},},
{{6,6,6,6,},{60,60,60,60,},{600,600,600,600,},},
Given your input and output in the example you posted, it seems to be just a transpose of the data, where n would be irrelevant.
If this is the case, the following code does this:
#include <vector>
#include <iostream>
void show3D_vector(std::vector<std::vector<std::vector<double>>>& a)
{
for (size_t i = 0; i < a.size(); ++i)
{
for (size_t j = 0; j < a[i].size(); ++j)
{
std::cout << "{";
for (size_t k = 0; k < a[i][j].size(); ++k)
{
if (k > 0)
std::cout << ",";
std::cout << a[i][j][k];
}
std::cout << "} ";
}
std::cout << std::endl;
}
}
template<typename T>
std::vector<std::vector<std::vector<T>>> Transpose(const std::vector<std::vector<std::vector<T>>>& vec)
{
if (vec.empty())
return {};
// Construct the output vector
std::vector<std::vector<std::vector<T>>>
outVect(vec[0].size(),
std::vector<std::vector<T>>(vec.size()));
// transpose loop
for (size_t row = 0; row < vec.size(); ++row)
{
for (size_t col = 0; col < vec[0].size(); ++col)
outVect[col][row] = vec[row][col];
}
return outVect;
}
int main()
{
std::vector<std::vector<std::vector<double>>> a =
{
{ {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} },
{ {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} },
{ {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} },
};
auto b = Transpose(a);
show3D_vector(b);
}
Output:
{1,1,1,1} {10,10,10,10} {100,100,100,100}
{2,2,2,2} {20,20,20,20} {200,200,200,200}
{3,3,3,3} {30,30,30,30} {300,300,300,300}
{4,4,4,4} {40,40,40,40} {400,400,400,400}
{5,5,5,5} {50,50,50,50} {500,500,500,500}
{6,6,6,6} {60,60,60,60} {600,600,600,600}
The other issue is that your show3d_vector function uses an incorrect type for the for loop counter. It should be size_t, not double.
I have a matrix (vector of vector), in other words, 2D vector (6 X 6) elements <double>, and after I have a vector with 6 elements <int>. the vector with ints has only "0" and "1". Then, I am looking for a way to remove a row and column of the 2D vector when a "0" is found in the vector (1D) of ints. This time is only 6 X 6 but later on, will be around 100 X 100.
What I've done is use iterators, and I successfully remove the rows but now I don't know how to tackle the columns.
This is my code.
#include <iostream>
#include <vector>
#include <iomanip>
int main() {
std::vector <int> boundaryConditions = { 0,1,1,1,0,0 };
std::vector <std::vector<double>> matrix = { {1.46371e+07, 1.46371e+07, -1.46371e+07, -1.46371e+07, 0, 0},
{1.46371e+07, 5.60371e+07, -1.46371e+07, -1.46371e+07, 0, -4.14e+07},
{-1.46371e+07, -1.46371e+07, 5.60371e+07, 1.46371e+07, -4.14e+07, 0},
{-1.46371e+07, -1.46371e+07, 1.46371e+07, 1.46371e+07, 0, 0},
{0, 0, -4.14e+07, 0, 4.14e+07, 0},
{0, -4.14e+07, 0, 0, 0, 4.14e+07}};
int i = 0;
std::vector<int>::iterator it = boundaryConditions.begin();
while (it != boundaryConditions.end())
{
if (*it == 0)
{
it = boundaryConditions.erase(it);
matrix.erase(matrix.begin() + i);
}
else
{
it++;
i++;
}
}
for (int i = 0; i < matrix.size(); i++)
{
for (int j = 0; j < matrix[i].size(); j++)
{
std::cout << matrix[i][j] << std::setw(15);
}
std::cout << "\n";
}
system("pause>0");
}
You can create a new matrix after you've removed the rows.
std::vector<std::vector<double>> removeColumns(const std::vector<int>& boundaryConditions,
const std::vector<std::vector<double>>& matrix)
{
std::vector<std::vector<double>> returnValue(matrix.size());
size_t curRow = 0;
size_t curCol = 0;
for (auto& v : returnValue)
{
for (size_t curCol = 0; curCol < matrix[0].size(); ++curCol)
{
if (boundaryConditions[curCol] == 1)
v.push_back(matrix[curRow][curCol]);
}
++curRow;
}
return returnValue;
}
Then you would call it like this, given that you have already removed the rows from matrix:
matrix = removeColumns({0,1,1,1,0,0}, matrix);
Here is a Live Example.
If you want an in-place solution, here is an example:
void removeColumns(const std::vector<int>& boundaryConditions, std::vector<std::vector<double>>& matrix)
{
size_t curCol = 0;
for (size_t i = 0; i < boundaryConditions.size(); ++i)
{
if (boundaryConditions[i] == 0)
{
for (auto& v : matrix)
v.erase(v.begin() + curCol);
}
else
++curCol;
}
}
Then it would be called like this:
removeColumns({0,1,1,1,0,0}, matrix);
Here is a Live Example
Another solution, if feasible for you, is to mark each entry to erase with a value, maybe std::numeric_limits<double>::max(). Then in a second pass, use erase/remove idiom, thus reducing the number of erase calls needed.
Here is an example:
void removeColumns(const std::vector<int>& boundaryConditions,
std::vector<std::vector<double>>& matrix)
{
// Mark the entries to delete
for (size_t i = 0; i < boundaryConditions.size(); ++i)
{
if (boundaryConditions[i] == 0)
std::for_each(matrix.begin(), matrix.end(),[&](std::vector<double>& vect)
{ vect[i] = std::numeric_limits<double>::max(); });
}
// One pass through the matrix to remove the marked entries.
for (auto& v : matrix)
v.erase(std::remove(v.begin(), v.end(), std::numeric_limits<double>::max()), v.end());
}
Here is a Live Example
Note that std::remove doesn't really remove anything, thus doesn't incur the penalty of an actual erase.
The single erase call erases an entire range, not just single values, thus has the potential to be faster than the first in-place solution given (but you have to time them, I can't guarantee which is faster).
Maybe this could help, not fully tested:
Let A be the binaryConditions array,
void reduce(std::vector<int> A, std::vector<int> &target) {
int i = 0, j = 0;
int nOnes = 0;
while (i<A.size() && j < A.size()) {
if (A[i] != 0) {
++i;
nOnes++;
}
else {
j = max(i + 1, j);
while (j < A.size() && A[j] == 0) ++j;
if (j >= A.size()) break;
swap(A[i], A[j]);
swap(target[i], target[j]);
}
}
A.resize(nOnes);
target.resize(nOnes);
}
I have a 2D vector, and i would like to sort all its columns by a sorting a specific row (the inner vectors) like this:
input:
{{5,6,9},
{1,7,5},
{3,5,7}}
sorting the elements to asc in row 2, the vector would be:
{{5,9,6},
{1,5,7},
{3,7,5}}
If stl sort is an acceptable choice, you can do like this:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
// According to your description, the input is row major
vector<vector<int>> vec_2d{
{5,6,9},
{1,7,5},
{3,5,7} };
// Convert the input vec to col major
int rows = vec_2d.size();
int cols = vec_2d.front().size();
// Allocate a new 2d vec which stores values by col major
vector<vector<int>> vec_2d_col_major(cols, vector<int>(rows));
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
vec_2d_col_major[j][i] = vec_2d[i][j];
}
}
// Sort by asc the 2nd row
sort(vec_2d_col_major.begin(), vec_2d_col_major.end(), [](const vector<int>& a, vector<int>& b) {
return a[1] < b[1];
});
// Copy data from col major to row major
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
vec_2d[i][j] = vec_2d_col_major[j][i];
}
}
// Check the sort result
for (const auto& row : vec_2d) {
for (auto num : row) {
cout << num << " ";
}
cout << endl;
}
}
Output:
5 9 6
1 5 7
3 7 5
I suppose your input vector is stored in row major by std::vector
sorted by reorder, use a vector to keep the order for each column.
#include <vector>
#include <algorithm>
#include <iostream>
template<class T>
void show(const std::vector<std::vector<T>>& values) {
for (auto& raw : values) {
for (auto& v : raw)
std::cout << v << " ";
std::cout << std::endl;
}
}
template<class T>
void swap(std::vector<std::vector<T>>& values, uint32_t i, uint32_t j) {
for (auto& row : values)
std::swap(row[i], row[j]);
}
template<class T>
void reorder(std::vector<std::vector<T>>& values, std::vector<uint32_t>& order) {
for (uint32_t i = 0; i < order.size(); ++i) {
while (order[i] != order[order[i]]) {
swap(values, order[i], order[order[i]]);
std::swap(order[i], order[order[i]]);
}
}
}
template<class T>
void sort_row(std::vector<std::vector<T>>& values, int32_t row) {
uint32_t row_count = values.size();
uint32_t col_count = values[row].size();
std::vector<uint32_t> sorted_idx(col_count);
for (uint32_t i = 0; i < col_count; ++i)
sorted_idx[i] = i;
std::sort(sorted_idx.begin(), sorted_idx.end(),
[&](uint32_t i, uint32_t j) {
return values[row][i] < values[row][j];
});
reorder(values, sorted_idx);
}
int main(int, char**) {
std::vector<std::vector<int32_t>> values = {
{-1, -3, -2, -4},
{ 0, 1, 2, 3},
{ 5, 6, 7, 8}
};
sort_row(values, 0);
show(values);
return 0;
}
Here is the program to find the pairs that sums up to 3.
For example:
INPUT : 0,3,5,1,2,4
OUTPUT: 0,3,1,2.
That means it should return all the pairs whose sum is equal to 3.
But I want to reduce the time complexity of this program. Right now I am using two nested for loops.
Can anyone suggest a better method to reduce the time complexity.
#include<iostream>
#include <vector>
using namespace std;
void main()
{
vector<int> v;
vector<int> r;
int x;
cout << "Enter the elements";
for(int i = 0; i < 6; i++)
{
cin >> x;
v.push_back(x);
}
for(int i = 0 ; i < v.size() - 1; i++)
{
for(int j = i + 1; j < v.size(); j++)
{
if(v[i] + v[j] == 3)
{
r.push_back(v[i]);
r.push_back(v[j]);
}
}
}
cout << "\noutput\n";
for(int i = 0 ; i < r.size(); i++)
{
cout<<r[i]<<"\n";
}
}
I'd do two preparation steps; First, eliminate all numbers > 3, as they will not be part of any valid pair. This reduces the complexity of the second step. Second, sort the remaining numbers such that a single walk through can then find all the results.
The walk through approaches the pairs from both ends of the sorted array; if a pair is found, both bounds can be narrowed down; if the current endings do sum up to a value > 3, only one boundary is narrowed.
Runtime complexity is O(N logN), where N is the count of elements <= 3; O(N logN) basically comes from sorting; the two single walk throughs will not count for large Ns.
int main(int argc, char* argv[]) {
const int N = 3;
std::vector<int> input{ 0,3,5,1,2,4};
std::vector<int>v(input.size());
int t=0;
for (auto i : input) {
if (i <= N) {
v[t++]=i;
}
}
std::sort (v.begin(), v.end());
long minIdx = 0;
long maxIdx = v.size()-1;
while (minIdx < maxIdx) {
int minv = v[minIdx];
int maxv = v[maxIdx];
if (minv+maxv == 3) {
cout << minv << '+' << maxv << endl;
minIdx++;maxIdx--;
}
else
minIdx++;
}
return 0;
}
You are searching for all the combinations between two numbers in n elements, more specifically, those that sum up to specific value. Which is a variation of the subset sum problem.
To make this happen you could generate all combinations without repetitions of the indexes of the vector holding the values. Here is an example of how to do this recursively and here is an example of how to do it iteratively, just to get an idea and possibly use it as a benchmark in your case.
Another approaches are dynamic programming and backtracking.
Late answer but works for negative integers too... For first, find the smallest number in the std::vector<int>, then like this answer says, remove all elements (or copy the opposite), which are higher than 3 + minimum. After sorting this std::vector<int> iterate through it from both ends with condition shown bellow:
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
std::vector<int> findPairs(const std::vector<int>& input, const int sum) {
int minElem = INT_MAX;
for(auto lhs = input.begin(), rhs = input.end() - 1; lhs < rhs;
++lhs, --rhs) {
const int elem = (*lhs < *rhs ? *lhs : *rhs);
if(elem < minElem)
minElem = elem;
}
std::vector<int> temp(input.size());
const auto tempBegin = temp.begin();
const auto tempEnd = std::remove_copy_if(input.begin(), input.end(),
temp.begin(), [minElem, sum](int elem) {
return (elem + minElem) > sum;
});
std::sort(tempBegin, tempEnd);
std::vector<int> result;
auto leftIter = tempBegin;
auto rightIter = tempEnd - 1;
while(leftIter < rightIter) {
if(*leftIter + *rightIter == sum) {
result.push_back(*leftIter++);
result.push_back(*rightIter--);
}
else {
if(sum - *leftIter < *rightIter) rightIter--;
else leftIter++;
}
}
return result;
}
int main() {
auto pairs = findPairs({ 0, 3, 5, 1, 2, 4, 7, 0, 3, 2, -2, -4, -3 }, 3);
std::cout << "Pairs: { ";
for(auto it = pairs.begin(); it != pairs.end(); ++it)
std::cout << (it == pairs.begin() ? "" : ", ") << *it;
std::cout << " }" << std::endl;
}
The code above will results the following:
Pairs: { -4, 7, -2, 5, 0, 3, 0, 3, 1, 2 }
I think you can solve this in O(n) with a map.
public void printPairs(int[] a, int v)
{
map<int, int> counts = new map<int, int>();
for(int i = 0; i < a.length; i++)
{
if(map.count(a[i]) == 0)
{
map[a[i]] = 1;
}
else
{
map[a[i]] = map[a[i]] + 1;
}
}
map<int, int>::iterator it = map.begin();
while(it != map.end())
{
int v1 = it->second;
if (map.count(v - v1) > 0)
{
// Found pair v, v1
//will be found twice (once for v and once for v1)
}
}
}
Hello I am looking for a way to write this C++ Code in a general way, so that if a want 20 columns I will not have to write 20 for loops:
for(int i=1; i<6; i++) {
for(int j=i; j<6; j++) {
for(int k=j; k<6; k++) {
for(int m=k; m<6; m++) {
std::cout << i << j << k << m << std::endl;
}
}
}
}
It is important that my numbers follow a >= Order.
I am very grateful for any help.
This recursive function should work:
#include <iostream>
bool inc( int *indexes, int limit, int n )
{
if( ++indexes[n] < limit )
return true;
if( n == 0 ) return false;
if( inc( indexes, limit, n-1 ) ) {
indexes[n] = indexes[n-1];
return true;
}
return false;
}
int main()
{
const size_t N=3;
int indexes[N];
for( size_t i = 0; i < N; ++i ) indexes[i] = 1;
do {
for( size_t i = 0; i < N; ++i ) std::cout << indexes[i] << ' ';
std::cout << std::endl;
} while( inc( indexes, 6, N-1 ) );
return 0;
}
live example
The design here is simple. We take a std::vector each containing a dimension count and a std::vector containing a current index at each dimension.
advance advances the current bundle of dimension indexes by amt (default 1).
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
return;
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which gives us an advance function for generic n dimensional coordinates.
Next, a filter that tests the restriction you want:
bool vector_ascending( std::vector<size_t> const& v ) {
for (size_t i = 1; (i < v.size()); ++i) {
if (v[i-1] < v[i]) {
return false;
}
}
return true;
}
then a for loop that uses the above:
void print_a_lot( std::vector<size_t> counts ) {
for( std::vector<size_t> v(counts.size()); v < counts; advance(v,counts)) {
// check validity
if (!vector_ascending(v))
continue;
for (size_t x : v)
std::cout << (x+1);
std::cout << std::endl;
}
}
live example.
No recursion needed.
The downside to the above is that it generates 6^20 elements, and then filters. We don't want to make that many elements.
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
{
size_t min = indexes[i];
// enforce <= ordering:
for (size_t j = i+i; j < counts.size(); ++j) {
if (indexes[j]<min)
indexes[j]=min;
else
break; // other elements already follow <= transitively
}
assert(vector_ascending(indexes));
return;
}
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which should do it without the vector_ascending check in the previous version. (I left the assert in to do testing).
This function works for me, but do not call it with 20 if you want it to finish.
#include <list>
#include <iostream>
std::list<std::list<int>> fun (std::list<std::list<int>> inputlist, int counter)
{
if(counter == 0)
{
return inputlist;
}
else
{
std::list<std::list<int>> outputlist;
for(std::list<int> oldlist : inputlist)
{
for(int i = 1; i<6; i++)
{
std::list<int> newlist = oldlist;
newlist.push_back(i);
outputlist.push_back(newlist);
}
}
return fun(outputlist, counter - 1);
}
}
int main()
{
std::list<int> somelist;
std::list<std::list<int>> listlist;
listlist.push_back(somelist);
std::list<std::list<int>> manynumbers = fun (listlist,5);
for (std::list<int> somenumbers : manynumbers)
{
for(int k : somenumbers)
{
std::cout<<k;
}
std::cout<<std::endl;
}
return 0;
}
Same with Processing (java) here :
void loopFunction(int targetLevel, int actualLevel, int min, int max, String prefix){
/*
targetLevel is the wanted level (20 in your case)
actualLevel starts from 1
min starts from 1
max is the max number displayed (6 in your case)
prefix starts from blank
see usage bellow (in setup function)
*/
for(int m=min; m<max; m++) {
if(targetLevel==actualLevel)
{
println(prefix+ " " + m);
}
else
{
loopFunction(targetLevel, actualLevel+1,m,max,prefix+ " " + m);
}
}
}
void setup(){
loopFunction(10,1,1,6,"");
}
Well, I am not the fastest in writing answer... when I started there was no other answer. Anyhow, here is my version:
#include <iostream>
#include <vector>
using namespace std;
class Multiindex {
public:
typedef std::vector<int> Index;
Multiindex(int dims,int size) :
dims(dims),size(size),index(Index(dims,0)){}
void next(){
int j=dims-1;
while (nextAt(j) && j >= 0){j--;}
}
Index index;
bool hasNext(){return !(index[0]==size-1);}
private:
bool nextAt(int j){
index[j] = index[j]+1;
bool overflow = (index[j]==size);
if (!overflow && j < dims-1){std::fill(index.begin() + j + 1,index.end(),index[j]);}
return overflow;
}
int dims;
int size;
};
int main() {
Multiindex m(4,6);
while (m.hasNext()){
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
m.next();
}
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
return 0;
}