Related
I'm working with C++ and found a problem. I want to pass an argument to a function. The argument must be a 2d array. When I try to do it, I get 2 errors:
Too many initializer values
and
initializing cannnot convert from initializer list to size_t**
How do I fix this? I've tried with changing it as 5x5 matrix, but it doesn't make it good.
size_t** matrix =
{
{1, 16, 20, 23, 25},
{6, 2, 17, 21, 24},
{10, 7, 3, 18, 22},
{13, 11, 8, 4, 19},
{15, 14, 12, 9, 5},
};
set<bool> set1 = iterateover(matrix);
The function:
std::set<bool> iterateover(size_t **arrayy)
size_t** matrix defines a pointer to a pointer to a size_t. An array is not a pointer. It can decay to a pointer, but in the case of a 2D array, it decays to a pointer to a 1D array, not to a pointer to a pointer.
The closest thing I can think of to what you seem to be after is
// here be the data
size_t actual_matrix[][5] = // note: We can omit the first dimension but we cannot
// omit the inner dimensions
{
{1, 16, 20, 23, 25},
{6, 2, 17, 21, 24},
{10, 7, 3, 18, 22},
{13, 11, 8, 4, 19},
{15, 14, 12, 9, 5},
};
// an array of pointers to the rows of actual data. This 1D array of pointers will
// decay to a size_t **
size_t * matrix[] =
{
actual_matrix[0],
actual_matrix[1],
actual_matrix[2],
actual_matrix[3],
actual_matrix[4],
};
// now we have the correct type to use with iterateover
std::set<bool> set1 = iterateover(matrix);
I want to pass an argument to a function. The argument must be a 2d array.
You can make iteratreOver a function template which can take a 2D array by reference, as shown below. You can make additional changes to the function according to your needs since it is not clear from the question what your iterateover function does. I have just printed all the elements inside the 2D array.
#include <iostream>
template<typename T,std::size_t N, std::size_t M>
void iterateOver(T (&arr)[N][M])
{
for(std::size_t i= 0; i < N; ++i)
{
for(std::size_t j = 0; j < M; ++j)
{
std::cout<<arr[i][j] <<" ";
}
std::cout<<std::endl;
}
}
int main()
{
size_t matrix[5][5] =
{
{1, 16, 20, 23, 25},
{6, 2, 17, 21, 24},
{10, 7, 3, 18, 22},
{13, 11, 8, 4, 19},
{15, 14, 12, 9, 5},
};
//call iterateOver by passing the matrix by reference
iterateOver(matrix);
}
The output of the above program can be seen here:
1 16 20 23 25
6 2 17 21 24
10 7 3 18 22
13 11 8 4 19
15 14 12 9 5
I use Maxima CAS to create the list:
a:makelist(i,i,1,20);
result:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
I want to slim the list and leave only every third element. To find it I check index i of the list a :
mod(i,3)>0
to find elements.
My code :
l:length(a);
for i:1 thru l step 1 do if (mod(i,3)>0) then a:delete(a[i],a);
Of course it does not work because length of a is changing.
I can do it using second list:
b:[];
for i:1 thru l step 1 do if (mod(i,3)=0) then b:cons(a[i],b);
Is it the best method ?
There are different ways to solve this, as know already. My advice is to construct a list of the indices you want to keep, and then construct the list of elements from that. E.g.:
(%i1) a:makelist(i,i,1,20);
(%o1) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
(%i2) ii : sublist (a, lambda ([a1], mod(a1, 3) = 0));
(%o2) [3, 6, 9, 12, 15, 18]
(%i3) makelist (a[i], i, ii);
(%o3) [3, 6, 9, 12, 15, 18]
The key part is the last step, makelist(a[i], i, ii), where ii is the list of indices you want to select. ii might be constructed in various ways. Here is a different way to construct the list of indices:
(%i4) ii : makelist (3*i, i, 1, 6);
(%o4) [3, 6, 9, 12, 15, 18]
One simple way (I do not know which one is best or faster) with compact code: makelist(a[3*i],i,1,length(a)/3)
Test example:
l1:makelist(i,i,1,12)$
l2:makelist(i,i,1,14)$
l3:[2,3,5,7,11,13,17,19,23,29]$
for a in [l1,l2,l3] do (
b:makelist(a[3*i],i,1,length(a)/3),
print(a,"=>",b)
)$
Result:
[1,2,3,4,5,6,7,8,9,10,11,12] => [3,6,9,12]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14] => [3,6,9,12]
[2,3,5,7,11,13,17,19,23,29] => [5,13,23]
I wrote a code for calculating the max subarray using brute force method. My code reads a number of arrays from an input file and returns the output file, which contains the max subarray and the sum value.
Everything works fine except the first max subarray on the output file always contains a really large number at the end, which gets added to the sum value. The subsequent sub-arrays don't have this problem. I've included an example at the bottom of this post.
I can't figure out where I went wrong. Any help would be greatly appreciated!
Here is the function that runs the algorithm and prints it to output file:
void a1(int a[], int size, string filename){
//run algorithm 1
int sum = a[0], start = 0, end = 0;
for (int x = 0; x < size; x++) {
int tempSum = 0;
int y = x;
while(y>=0){
tempSum += a[y];
if(tempSum>sum){
sum=tempSum;
start=y;
end=x;
}
y--;
}
}
//print results on file
ofstream output;
output.open(filename.c_str(), ios::out | ios::app);
output << "\nMax sum array: ";
for (int x = start; x <= end; x++) {
output << a[x];
if (x != end) output << ", ";
}
output << "\nMax sum value: " << sum << "\n";
output.close();
}
Here is the main file:
int main() {
int a[50];
ifstream inputFile;
string s;
stringstream ss;
string outputfile = "MSS_Results.txt";
//print title
ofstream output;
output.open(outputfile.c_str(), ios::out | ios::app);
output << "Algorithm 1:\n";
output.close();
//read file and run a1
int size;
char c;
inputFile.open("MSS_Problems.txt");
while (!inputFile.eof()) {
getline(inputFile, s);
size = 0;
ss << s;
ss >> c;
while (ss.rdbuf()->in_avail()) {
ss >> a[size];
size++;
ss >> c;
if (!ss.rdbuf()->in_avail() && c != ']') {
ss.clear();
getline(inputFile, s);
ss << s;
}
}
ss.clear();
if (size > 0) a1(a, size, outputfile);
}
inputFile.close();
return 0;
}
Example of input file:
[1, 2, 4, -1, 4, -10, 4, -19, 18, -1, -3, -4, 11, 3, -20, 19, -33, 50, 66, -22, -4, -55, 91, 100, -102, 9, 10, 19, -10, 10, 11, 11, -10, -18, 50, 90]
[12, 12, 14, -88, -1, 45, 6, 8, -33, 2, 8, -9, -33, -8, -23, -77, -89, 1, 9, 10, 92, 87]
[565, 78, 33, 9, 10, 84, 71, -4, -22, -55, -10, 76, -9, -9, -11, 76, 89, 11, 10, -33, 9]
[2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
Example of output file:
Algorithm 1:
Max sum array: 50, 66, -22, -4, -55, 91, 100, -102, 9, 10, 19, -10, 10, 11, 11, -10, -18, 50, 90, 3897136
Max sum value: 3897432
Max sum array: 1, 9, 10, 92, 87, 91
Max sum value: 290
Max sum array: 565, 78, 33, 9, 10, 84, 71, -4, -22, -55, -10, 76, -9, -9, -11, 76, 89, 11, 10, -33, 9, 87
Max sum value: 1055
Max sum array: 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 11
Max sum value: 103
As you can see, for the first array, there is a 3897136 that does not belong to the original array.
If I delete the first line from the input, the input looks like this:
[12, 12, 14, -88, -1, 45, 6, 8, -33, 2, 8, -9, -33, -8, -23, -77, -89, 1, 9, 10, 92, 87]
[565, 78, 33, 9, 10, 84, 71, -4, -22, -55, -10, 76, -9, -9, -11, 76, 89, 11, 10, -33, 9]
[2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
Now my output looks something like this:
Algorithm 1:
Max sum array: 1, 9, 10, 92, 87, 624
Max sum value: 823
Max sum array: 565, 78, 33, 9, 10, 84, 71, -4, -22, -55, -10, 76, -9, -9, -11, 76, 89, 11, 10, -33, 9, 87
Max sum value: 1055
Max sum array: 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
Max sum value: 92
I initialized the array incorrectly, which is why it sometimes gave me a garbage number at the end. To initialize properly, I simply changed
a[100];
to
a[100] = {0}
and that fixed the problem of abnormally large numbers at the end of the array.
I then moved a[100] = {0} into the while loop where the code reads the input file. That seems to have fixed the new issue of reading wrong elements into the array.
Final unresolved issue: 0 at the end of array.
Will update once I solve that.
Since all the problem is finding the maximum subarray , therefore the "large number" at the end will need to get added to produce the correct results.
In the first example that you provided, all the numbers were positive.
This means that the maximum sum subarray will actually be the sum of all the array elements.
Your algorithm part is OK;
Since the question would be a bit long, ill add that here, I also want to add a row in a vector to the Finald vector.
MatrixXf ProdA(7, 7);;
VectorXf Intd(7);
VectorXf Finald(7);
ProdA <<
7, 5, 1, 9, 11, 2, 0,
5, 2, 8, 3, 11, 3, 3,
3, 9, 0, 1, 3, 1, 7,
6, 0, 1, 9, 11, 33, 3,
3, 5, 3, 3, 4, 3, 3,
3, 9, 1, 1, 0, 1, 15,
6, 2, 6, 2, 5, 12, 3,
Intd << 4, 5, 2, 12, 4, 1, 6;
Finald << 0, 0, 0, 0, 0, 0, 0;
for (int i = 0; i < 7; i++){
Finald.row(i) += ProdA.rowwise().sum();
Finald.row(i) += Intd.row(i);
}
So far this is what I have got. Obviously I get an error if I put i in rowwise. So as an example, I want to add the first row of ProdA , and the first number of Intd into the first space in the Finald vector, and then loop through every row of ProdA and Intd, and sum them all into Finald.
Thanks in advance!
I'm not 100% certain that I correctly understand your problem, but the way I understood it, this should work:
VectorXf ones(7);
ones << 1, 1, 1, 1, 1, 1, 1;
Finald = ProdA * ones + Intd;
I'm not sure if your matrix library (which seems to be Eigen) stores vectors as row or column vectors. So you might have to use ones.transpose() instead.
I need to port a snippet written in Python to C++
but that snippet is using combinations from itertools in python.
The line that I'm really interested to porting over to C++ is this one:
for k in combinations(range(n-i),2*i):
range(n-i) in Python will generate a list from 0 to (n-i) - 1
Let n = 16, i = 5
print range(n-i)
outputs:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
and python combinations will generate all possible combinations in that list.
e.g.
print list(combinations(range(n-i),2*i))
outputs:
[(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 10),
(0, 1, 2, 3, 4, 5, 6, 7, 9, 10),
(0, 1, 2, 3, 4, 5, 6, 8, 9, 10),
(0, 1, 2, 3, 4, 5, 7, 8, 9, 10),
(0, 1, 2, 3, 4, 6, 7, 8, 9, 10),
(0, 1, 2, 3, 5, 6, 7, 8, 9, 10),
(0, 1, 2, 4, 5, 6, 7, 8, 9, 10),
(0, 1, 3, 4, 5, 6, 7, 8, 9, 10),
(0, 2, 3, 4, 5, 6, 7, 8, 9, 10),
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)]
I want to generate similar output using std::vector and next_permutation from C++ but I'm still getting erroneous results. This is my current approach:
for(int j = 0; j < n-i; j++) {
temp_vector.push_back(j);
}
That snippet is equivalent to range(n-i) in Python.
But the following snippet:
do {
myvector.push_back(temp_vector);
} while(next_permutation(temp_vector.begin(),temp_vector.begin()+2*i));
cout<<myvector.size()<<endl;
Is not equivalent to combinations(range(n-i),2*i)) in Python, and I've tried many variations and still haven't been able to come up with the results I'm expecting.
For example:
Let n = 16
i = 5
Python
>>> print len(list(combinations(range(n-i),2*i)))
11
C++
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> temp_vector;
vector< vector<int> > myvector;
int n = 16, i = 5;
for(int j = 0; j < n - i; j++) {
temp_vector.push_back(j);
}
do {
myvector.push_back(temp_vector);
} while(next_permutation(temp_vector.begin(), temp_vector.begin()+2*i));
cout<<myvector.size()<<endl;
return 0;
}
g++ combinations.cpp
./a.out
3628800
Any guidance will be greatly appreciated! Thanks a lot!
combinations and permutations are not the same thing.
A combination is an unordered list of a subset of the items from another set. A permutation is a unique order of the items in the list.
You're generating all combinations of 10 things from a list of 11 things, so you'll get 11 results, each one missing a different one of the original 11 items.
Generating every permutation will generate every unique order of the original 11 items. Since the items in this case are all unique that means the result would be 11! lists where each contains all 11 items. You're only generating permutations from the first 10 items however, so you're getting 10! lists, none of which contain the 11th item.
You need to find an algorithm for generating combinations instead of permutations.
There's no built-in algorithm for combinations. std::next_permutation can be used as part of an algorithm to generate combinations: See Generating combinations in c++.
Here's an old draft proposal for algorithms for combinations, including code.