Order 2D Arrays based on a sum of each row in C++ - c++

The questions pretty much sums it up. Here's what I have so far:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int sum1;
int sum2;
int sum3;
int sum4;
int sum5;
int sum6;
int sum7;
int sum8;
int a[8][7] = {
{ 2, 4, 3, 4, 5, 8, 8 } ,
{ 7, 3, 4, 3, 3, 4, 4 } ,
{ 3, 3, 4, 3, 3, 2, 2 } ,
{ 9, 3, 4, 7, 3, 4, 1 } ,
{ 3, 5, 4, 3, 6, 3, 8 } ,
{ 3, 4, 4, 6, 3, 4, 4 } ,
{ 3, 7, 4, 8, 3, 8, 4 } ,
{ 6, 3, 5, 9, 2, 7, 9 }
};
for(int i = 0; i < 8; i++) {
}
}
I'm planning on assigning the sum of each value from sum1 to sum8 to a row, then order each row by its total sum and display it to the user.
However, I keep getting stuck and can't find any good documentation. Can anyone help me write an effective function I can loop through in my for loop to add each of the rows to a sum, then return the sum and average all the rows out? (this will likely have to be more than one function but...whatever.)

If you want the sum of each row displayed in ascending order, the following code will do that...
// #include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
int sums[8] = {0};
int a[8][7] = {
{ 2, 4, 3, 4, 5, 8, 8 } ,
{ 7, 3, 4, 3, 3, 4, 4 } ,
{ 3, 3, 4, 3, 3, 2, 2 } ,
{ 9, 3, 4, 7, 3, 4, 1 } ,
{ 3, 5, 4, 3, 6, 3, 8 } ,
{ 3, 4, 4, 6, 3, 4, 4 } ,
{ 3, 7, 4, 8, 3, 8, 4 } ,
{ 6, 3, 5, 9, 2, 7, 9 }
};
// calculate the sums
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 7; j++) {
sums[i] += a[i][j];
}
}
sort(begin(sums), end(sums)); // sort the sums
copy(begin(sums), end(sums), ostream_iterator<int>(cout, " ")); // display the sums
return 0;
}

I see you are a cool programmer. You do not seek an easy way.
Of course you could use an array of sums but it seems it is too easy.
Well, then try the following
#include <iostream>
#include <numeric>
int main()
{
int sum1;
int sum2;
int sum3;
int sum4;
int sum5;
int sum6;
int sum7;
int sum8;
int a[8][7] = {
{ 2, 4, 3, 4, 5, 8, 8 } ,
{ 7, 3, 4, 3, 3, 4, 4 } ,
{ 3, 3, 4, 3, 3, 2, 2 } ,
{ 9, 3, 4, 7, 3, 4, 1 } ,
{ 3, 5, 4, 3, 6, 3, 8 } ,
{ 3, 4, 4, 6, 3, 4, 4 } ,
{ 3, 7, 4, 8, 3, 8, 4 } ,
{ 6, 3, 5, 9, 2, 7, 9 }
};
size_t i = 0;
for ( auto p : { &sum1, &sum2, &sum3, &sum4, &sum5, &sum6, &sum7, &sum8 } )
{
*p = std::accumulate( a[i], a[i] + 7, 0 );
++i;
}
for ( int x : { sum1, sum2, sum3, sum4, sum5, sum6, sum7, sum8 } ) std::cout << x << std::endl;
}
The output is
34
28
20
31
32
28
37
41
Having the sums you can find any average. I hope you will do this yourself.

Related

getting "Too Many Initializer Values" error in 2D array

void Data::Paramters()
{
for (int i = 0; i < I; i++)
{
mc[i] = new int[K];
for (int k = 0; k < K; k++)
{
mc[i][k] = {{1, 0, 2, 3, 5},{ 4, 2, 2, 1, 3 }, { 4, 3, 4, 1, 3 }, { 3, 5, 6, 4, 2 } };
}
}
}
getting "Too Many Initializer Values" error in starting of { 4, 2, 2, 1, 3 }
where I=5 and K=4
The initializer is for a 4x5 2D matrix, so you should just write:
enum { I = 4, K = 5 };
int mc[I][K] = { { 1, 0, 2, 3, 5 },
{ 4, 2, 2, 1, 3 },
{ 4, 3, 4, 1, 3 },
{ 3, 5, 6, 4, 2 } };
The expression mc[i][k] has the type int. It is not an array.
So this assignment statement
mc[i][k] = {{1, 0, 2, 3, 5},{ 4, 2, 2, 1, 3 }, { 4, 3, 4, 1, 3 }, { 3, 5, 6, 4, 2 } };
does not make a sense.
If K is a constant expression then you can allocate and initialize the two-dimensional array the following way
int ( *mc )[K] = new int[I][K]
{
{ 1, 0, 2, 3, 5 },
{ 4, 2, 2, 1, 3 },
{ 4, 3, 4, 1, 3 },
{ 3, 5, 6, 4, 2 }
};
Here is a demonstration program.
#include <iostream>
int main()
{
const size_t K = 5;
size_t I = 4;
int ( *mc )[K] = new int[I][K]
{
{ 1, 0, 2, 3, 5 },
{ 4, 2, 2, 1, 3 },
{ 4, 3, 4, 1, 3 },
{ 3, 5, 6, 4, 2 }
};
for ( size_t i = 0; i < I; i++ )
{
for (const auto &item : mc[i])
{
std::cout << item << ' ';
}
std::cout << '\n';
}
}
The program output is
1 0 2 3 5
4 2 2 1 3
4 3 4 1 3
3 5 6 4 2

Runtime library error connected with vector

This is my code which task is to check how many times does the number appear in my array.
Error message tells me that vector subscript is out of range.
int main() {
vector<int> numbers(1,-1);
int x;
int z;
bool exit;
int digits[] = { 2, 4, 5, 3, 2, 5, 6, 3, 5, 7, 9, 2, 1, 2, 3, 4, 5, 6, 4, 3, 2, 6, 3, 4, 4, 1, 3, 7, 9, 5, 9, 2, 3, 1, 2, 3, 4, 5, 6, 2, 1, 2, 3, 4, 5, 3, 2, 7, 7, 7 };
for (int i = 0; i < (sizeof(digits) / sizeof(int)); i++) {
z = 0;
bool exit = 1;
for (int j = 0; j < (sizeof(digits) / sizeof(int)); j++) {
x = digits[i];
for (int y = 0; y < (sizeof(numbers) / sizeof(int)); y++) {
if (x == numbers[y]) {
bool exit = 0;
}
}
if (digits[j] == x && exit) {
z++;
}
}
if (exit) {
cout << "Liczba: " << x << " wystepuje: " << z << " razy" << endl;
numbers.push_back(x);
}
}
}
Visual studio tells me that my code is valid but then during compilation , cmd shows me the error message which tells me that Vector subscript out of range . I just can't figure it out how to fix it exactly , bcs i have not found that i would initialize the vector which would not exist .
At least this statement
for (int y = 0; y < (sizeof(numbers) / sizeof(int)); y++) {
does not make sense because the expression sizeof(numbers) / sizeof(int) does not yield the number of elements in the vector. Instead use
for (int y = 0; y < numbers.size(); y++) {
If I have correctly understood your task then instead of the container std::vector it is better to use either std::map or std::unordered_map.
For example
#include <iostream>
#include <map>
int main()
{
int digits[] =
{
2, 4, 5, 3, 2, 5, 6, 3, 5, 7,
9, 2, 1, 2, 3, 4, 5, 6, 4, 3,
2, 6, 3, 4, 4, 1, 3, 7, 9, 5,
9, 2, 3, 1, 2, 3, 4, 5, 6, 2,
1, 2, 3, 4, 5, 3, 2, 7, 7, 7
};
std::map<int, size_t> frequency;
for ( const auto &item : digits )
{
++frequency[item];
}
for ( const auto &p : frequency )
{
std::cout << p.first << ": " << p.second << '\n';
}
return 0;
}
The program output is
1: 4
2: 10
3: 10
4: 7
5: 7
6: 4
7: 5
9: 3

printing all increasing subsequence using recursion

I'm trying to print all increasing subsequence with following.
But it is not working accordingly.
Please explain what actually my code doing.
I'm stuck since last 1 week.
But unable to figure out.
#include <bits/stdc++.h>
using namespace std;
int temp[1000];
int ans = 1;
int cnt = 0;
void solve(int *arr, int n, int k)
{
if(k == n){
cnt++;
for(int j = 0; j < n; j++){
cout<<temp[j]<<" ";
}
cout<<endl;
return;
}
for(int i = k; i < n; ++i){
if(arr[k] <= arr[i]){
temp[k] = -2;
solve(arr, n, i+1);
temp[k] = 2;
}
}
}
int main()
{
int arr[] = {4, 1, 13, 7, 0, 2, 8, 11, 3};
//int arr[] = {-1, 1 ,2, 3, 4};
//int arr[] = {-1,1,2,3,4,11, 5,6, 2, 9};
memset(temp, -1, sizeof(temp));
solve(arr, 9, 0);
cout<<cnt<<endl;
return 0;
}
Output should be total number of enumerating increasing subsequence.
This prints all increasing subsequences:
void print(const vector<int> v) {
for (size_t i = 0; i < v.size() - 1; ++i)
cout << v[i] << ", ";
cout << v.back() << endl;
}
int solve(const vector<int>& v, size_t start, vector<int>& sequence) {
print(sequence);
int count = 1;
for (size_t i = start; i < v.size(); ++i) {
if (v[i] >= sequence.back()) {
sequence.push_back(v[i]);
count += solve(v, i + 1, sequence);
sequence.pop_back();
}
}
return count;
}
size_t solve(const vector<int>& v) {
int count = 0;
for (size_t i = 0; i < v.size(); ++i) {
vector<int> sequence{v[i]};
count += solve(v, i + 1, sequence);
}
return count;
}
Usage:
vector<int> v{4, 1, 13, 7, 0, 2, 8, 11, 3};
auto count = solve(v);
cout << "Count: " << count << endl;
Output:
4
4, 13
4, 7
4, 7, 8
4, 7, 8, 11
4, 7, 11
4, 8
4, 8, 11
4, 11
1
1, 13
1, 7
1, 7, 8
1, 7, 8, 11
1, 7, 11
1, 2
1, 2, 8
1, 2, 8, 11
1, 2, 11
1, 2, 3
1, 8
1, 8, 11
1, 11
1, 3
13
7
7, 8
7, 8, 11
7, 11
0
0, 2
0, 2, 8
0, 2, 8, 11
0, 2, 11
0, 2, 3
0, 8
0, 8, 11
0, 11
0, 3
2
2, 8
2, 8, 11
2, 11
2, 3
8
8, 11
11
3
Count: 48

How to insert element at beginning of vector

vector<int>grid = { 0, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 2, 4, 1, 5, 3, 3, 6, 2, 6, 4, 5, 5, 5, 3, 6, 2, 6, 4, 4, 5, 5, 5, 6, 6, 6, 4, 7, 7, 8, 5, 8, 8, 8, 4, 7, 7, 8, 8, 8, 8, 8, 4, 7, 7, 7, 7, 8, 8, 8 };
const size_t gridSize = end(grid) - begin(grid);
int maxColour = *max_element(begin(grid), end(grid));
vector<vector<int>> colourPos(maxColour+1);
for (size_t i = 1; i < gridSize; ++i)
colourPos[grid[i]].push_back(i);
for (size_t i = 0; i < colourPos.size(); ++i) {
std::cout << (i + 1) << ": ";
for (int p : colourPos[i])
std::cout << p << ' ';
std::cout << std::endl;
}
How can I insert an element at colourPos[1][0] so that it shifts all elements, and also to the other vectors within the colourPos vector?
e.g [2][0], [3][0].
I tried
colourPos[1][0].insert(0);
and just got "expression must have class type"
insert takes an iterator to indicate where to insert. To insert at the beginning of colourPos[1]:
colourPos[1].insert(colourPos[1].begin(), 0);
This insertion works:
vector<int> &cp1 = colourPos[1]; // & means reference to the subarray
cp1.insert(cp1.begin(), 2); // insertion

Inserting multiple elements into a 2D block

I am attempting to calculate the energy of a series of elements inside a vector of vectors. As soon as the particular element has the right energy, it is then pushed into another vector of vectors. Here is an example because it is hard to explain:
bool energy(const std::vector<double> &vals)
{
float sum = 0.0;
for(unsigned i=0; (i < vals.size()); i++)
{
sum += (vals[i]*vals[i]);
}
//cout << sum << endl;
return (sum >= 5);
}
int main(int argc, char *argv[]) {
std::vector<vector<double> > vals {
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 2, 1, 1, 1}, //This has an energy of "5" -> push_back to vector[0]
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count && start a new
// vector
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5} // This has an energy of "55" -> push_back to vector[1]
};
std::vector<vector<double> > clusters;
std::vector<vector<double> > tmp;
//std::for_each(vals.begin(), vals.end(), energy);
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i]))
{
clusters.resize(j + 1);
clusters[j] = vals[i];
}else if(!energy(vals[i]) && energy(vals[i+1]))
{
j++;
}
}
for(unsigned i=0; (i < clusters.size()); i++)
{
for(unsigned j=0; (j < clusters[i].size()); j++)
{
cout << clusters[i][j] << ' ';
}
cout << endl;
}
}
What should happen
There should be 2 elements of the vector of vectors named clusters each containing the values of:
clusters[0] = {
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 2, 1, 1, 1
};
`clusters[1] = 1, 2, 3, 4, 5,
1, 2, 3, 4, 5,
1, 2, 3, 4, 5,
1, 2, 3, 4, 5}`
What is happening?
The vector of vectors seem to be over-riding the blocks that get inserted into them. So instead of the above, I just get the last element that it found so:
`cluster[0] = {1 2 1 1 1}
cluster[1] = {1 2 3 4 5}`
What I was thinking and attempting was to store each of the "blocks" inside a vector of vectors that contain the sufficient energy and then push all these values inside a vector<double> and then insert this vector inside the block of clusters..
Is there an alternative way, a much simpler solution to this problem?
Corrected code:
#include<vector>
#include<iostream>
using namespace std;
bool energy(const std::vector<double> &vals)
{
float sum = 0.0;
for(unsigned i=0; (i < vals.size()); i++)
{
sum += (vals[i]*vals[i]);
}
//cout << sum << endl;
return (sum >= 5);
}
int main(int argc, char *argv[]) {
std::vector<vector<double> > vals {
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 2, 1, 1, 1}, //This has an energy of "5" -> push_back to vector[0]
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count && start a new
// vector
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5} // This has an energy of "55" -> push_back to vector[1]
};
std::vector<vector<double> > tmp(vals.size());
std::vector<vector<double> > clusters(vals.size());
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i]))
{
clusters[j].insert(clusters[j].end(), vals[i].begin(), vals[i].end());
}else if(!energy(vals[i]) && energy(vals[i+1]))
{
j++;
}
}
for(unsigned i=0; (i < clusters.size()); i++)
{
for(unsigned j=0; (j < clusters[i].size()); j++)
{
cout << clusters[i][j] << ' ';
}
cout << endl;
}
}
The output is:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
Your problem is here:
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i]))
{
clusters.resize(j + 1);
clusters[j] = vals[i];
}
else if(!energy(vals[i]) && energy(vals[i+1]))
{
j++;
}
}
First of all, your energy function returns an int, so when the return value is non-zero, it will evaluate the condition to true, and when it is 0, it will be false.
Second, you are effectively doing a push_back in the if branch, but you are only pushing the current vector (you aren't appending it to an existing vector).
To fix this, I would recommend using a map<int, vector<int>> so you can quickly reference each cluster (e.g. the ones with energy of 5 would have a key of 5, so you would either create a new vector and insert those values, or append to the one that already exists there). If you need it in a vector of vectors, you can always iterate through the map after you have them sorted and swap them into the vector of vectors.
you could simplify a lot your code, so it would be much more easy to read and understand, for example take you energy function, you could write it in a single line using algorithms:
return std::inner_product(vals.begin(), vals.end(), vals.begin(), 0.) >= 5;
I changed a piece of code make it works
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i])) {
clusters[j].insert(clusters[j].end, vals[i].begin(), vals[i].end());
}
if(!energy(vals[i]) && energy(vals[i+1])) {
clusters.push_back( tmp );
++j;
}
}
Don't use resize. You can just push_back an empty vector into your clusters.
And for each operation to append a vector, just using insert by range
void insert (iterator position, InputIterator first, InputIterator last);
Ref: http://en.cppreference.com/w/cpp/container/vector/insert