Split a vector into n sub vectors (rebound) - c++

I am trying to split a vector into n parts.
I checked the following solution How to split a vector into n "almost equal" parts
I came out with the following code based on this comment :
To get a base number for the size of each part, simply divide the total by the number of parts: 11/3 = 3. Obviously some of the parts will need to be bigger than that to get the proper total, but that's just the remainder: 11 % 3 = 2. So now you know that 2 of the parts will be size 3+1, and whatever's left over will be 3. (Mark Ransom)
int main()
{
std::vector<int> lines;
int size = 200;
for(int i = 0; i < size;i++)
{
lines.push_back(i);
}
int p = 6;
int right = round((double)size/(double)p);
for(int i = 0; i < p;i++)
{
if( i < size - left)
{
vector<int> v;
for(int j = 0; j < right; j++)
{
v.push_back(lines[j]);
}
cout << v.size() << endl;
}
else if (i > size - left)
{
vector<int> v;
for(int k = 0; k < right; k++)
{
v.push_back(lines[k]);
}
cout << v.size() << endl;
}
}
return 0;
}
Output with p = 6 and size = 200 is : 33,33,33,33,33,33 = 198
Output with p = 6 and size = 1000 is : 167,167,167,167,167,167 = 1002
both outputs are wrong. What am i missing?
After editing:
So Let me understand.
We increment i by right which represents the size of a chunk or sub-vector.
While i is less than the size-right we do nothing. When i becomes greater we have to deal with the Leftovers we change the size of the chunk by right = size - i.
int main()
{
std::vector<int> lines;
int size = 1000;
for(int i = 0; i < size;i++)
{
lines.push_back(i);
}
int p = 6;
int right = round((double)size/(double)p);
int left = size % p;
for(int i = 0; i < size; i+= right)
{
if(i < size - right)
{
vector<int> v;
//MAJOR CORRECTION
for(int j = i; j < (i+right); j++)
{
v.push_back(lines[j]);
}
cout << v.size() << endl;
}
else
{
right = size - i;
vector<int> v;
//Major Correction
for(int k =i; k < size; k++)
{
v.push_back(lines[k]);
}
cout << v.size() << endl;
}
return 0;
}
Thank you.
output: 33 33 33 33 33 33 2 = 200

int right = size/p; // don't round! this floors.
int left = size % p; // this one is correct.
for(int i = 0; i < p;i++)
{
if( i < size - left)
{
vector<int> v;
for(int j = 0; j < right; j++) // counters, you used i here.
{
v.push_back(lines[j]); // and here.
}
cout << v.size() << endl;
}
else if (i >= size - left)// sorry equal is here. try >= not > , comment with results.
{
vector<int> v;
for(int j = 0; j < right+1; j++) // and here
{
v.push_back(lines[j]); // and here
}
cout << v.size() << endl;
}
}

Think your idea in other way:
p (parts) = 3, size = 11, ceil(11/3) = 4 so 4+4+3 = 11
same for other
p = 6, size = 200 ceil(200/6) = 34 so, 34+34+34+34+34+30 = 200
int p = 6;
size_t nLimit = ceil((double)lines.size()/p);
// if you don't want to contain the leftover element within p elements, use floor
vector<int>::iterator start = lines.begin();
for(size_t i = 0; i < lines.size(); i+=nLimit){
// Just use the constructor/insert function
vector<int> v(start+i, start+std::min<size_t>(i+nLimit, lines.size()));
cout<<v.size()<<endl;
}
Working code here:
http://ideone.com/6V7rSX

Related

I need to print this shape in c++ but I am having issue with last row

image of shape
I have no issues with first 4 rows. 5th row is the problem. I am required to use loops but dont know how i am suppose to print 6 (-.*) with 0 spaces when all rows above follow a pattern.
Something like this should work for you
for (int i = 1; i <= 6; i++) {
for (int j = 28 - i * 3; j >= 0; j--) {
std::cout << " ";
}
for (int j = 0; j < i; j++) {
std::cout << "-.*";
}
std::cout << std::endl;
if (i == 4) i++;
}
Basically check when you are on the 4th row and just have it skip a row by incrementing your row index loop.
Something like this?
std::string repeat(std::string s, int n) {
std::string repeat;
for (int i = 0; i < n; ++i)
repeat += s;
return repeat;
}
int main()
{
int PADDING = 20;
int MAX = 7;
for (int i = 1; i < MAX; ++i) {
if (i == 5) continue;
std::string padding(3*(PADDING-MAX-i), ' ');
std::cout << padding << repeat("-.*", i) << std::endl;
}
}
Output:
-.*
-.*-.*
-.*-.*-.*
-.*-.*-.*-.*
-.*-.*-.*-.*-.*-.*
Live demo:
http://cpp.sh/6mtpx
In C (not C++):
#include <stdio.h>
int main(void) {
int height = 5;
char txt[3*height+1];
char sym[]= "-.*";
for(int i=0; i<3*height; ++i) txt[i]=sym[i%3];
txt[3*height]=0;
for(int i=0; i<height; ++i)
printf("%s%*.*s\n", (i+1==height)? &txt[3*(height-1)] : "", 3*(height+(i+1<height)), (i+1)*3, txt);
return 0;
}
Output:
Success #stdin #stdout 0s 5476KB
-.*
-.*-.*
-.*-.*-.*
-.*-.*-.*-.*
-.*-.*-.*-.*-.*-.*
IDEOne Link

Segmentation fault in matrix multiplication C++

I'm trying to make a function that receives as parameter two matrixes and returns the multiplication of both. But when I try to test it, it returns a segmentation fault, can anyone tell me why? And help me to fix it?
This is my function code:
#include <iostream>
#include <math.h>
#include <fstream>
#include <vector>
using namespace std;
vector<vector<double> > MMultiplication(vector<vector<double> > a, vector<vector<double> > b) {
int a_columns = a[0].size();
int a_rows = a.size();
int b_columns = b[0].size();
int b_rows = b.size();
< vector<vector<double> > result;
result.resize(a_columns);
for (int i = 0; i < m; ++i)
{
//Grow Columns by b_rows
result[i].resize(b_rows);
}
for (int p = 0; p < a_rows; p++) {
for (int q = 0; q < b_columns; q++) {
result[p][q] = 0;
}
}
if (a_columns != b_rows) {
cout << "Error: The number of columns of the first matrix needs to be equal to the number of rows of the second matrix" << endl;
return result;
}
for (int i = 0; i < a_rows; i++) { //i iterate a rows
for (int j = 0; j = b_columns; j++) //j iterates b columns
{
for (int k = 0; k < a_columns; k++) { //k goes back to a and iterates its columns
result[i][j] += a[i][k] * b[k][j]; //sums all multiplications into result[i][j]
}
}
}
return result;
}
And this is the main i'm using to test my function:
int main ()
{
vector < vector < double >>a;
int m = 4, n = 2;
//Grow rows by m
a.resize (m);
for (int i = 0; i < m; ++i)
{
//Grow Columns by n
a[i].resize (n);
}
a[0] =
{
1, 0};
a[1] =
{
1, 1};
a[2] =
{
1, 2};
a[3] =
{
1, 3};
cout << a.size () << endl;
cout << a[0].size () << endl;
vector < vector < double >>b;
int o = 2, p = 4;
b.resize (o);
for (int i = 0; i < o; i++)
{
b[i].resize (p);
}
b[0] =
{
1, 2, 3, 4};
b[1] =
{
1, 3, 5, 7};
vector < vector < double >>result = MMultiplication (a, b);
cout << result.size () << endl;
cout << result[0].size () << endl;
/* for(int k = 0; k < result.size(); k++) {
for(int q = 0; q < result[0].size(); q++)
cout << result[k][q] << endl;
} */
}
Also, it's important to point out that the function, so far, is returning a matrix of zeros if it's impossible to multiply a and b.
Thank you.

how I can store some arrays in a 2 dimension vector?

I have a loop in each iterate an array is printed. now I need this array so I want to put them in a 2 dimension vector. I wrote this code but I dont know why it does not work!
when I run it does not print any thing and it dont show any error!
int main() {
int i, u;
const int j = 9;
vector<vector<int>> V;
int B[9] = {};
for (int r = 0; r<10; r++) {
B[r] = 1;
for (int t = 0; t<V.size(); t++) {
for (int w = 0; w<j; w++, u++) {
V[t][w] = B[u];
}
}
}
for (int m = 0; m<V.size(); m++) {
for (int k = 0; k<j; k++) {
cout << "V=" << " " << V[m][k];
}
}
return 0;
}
For example in the first loop in each iterate B changes and I want to store all of them in a matrix! for example I have:
first iterate: B=(1,0,0)
second iterate: B=(0,1,0)
third iterate: B=(0,0,1)
now I want to have:
V={{1,0,0},{0,1,0},{0,0,1}}
Let's say that you have N int[N] values, and you want 1 vector<vector<int>> value.
std::vector<int> fromArray(int (&B)[N])
{
return { std::begin(B), std::end(B) };
}
This is a function that will turn a 1D array into a 1D vector. you will need to call it N times.
std::vector<std::vector<int>> fromArrays(int (&Bs)[N][N])
{
std::vector<std::vector<int>> result{ N };
std::transform(std::begin(Bs), std::end(Bs), result.begin(), fromArray);
return result;
}
Here we take a 2D array and turn it into a 2D vector. This requires you have all the Bs together.
int main()
{
constexpr int N = 3;
std::vector<std::vector<int>> V;
for (int i = 0; i < N; ++i)
{
int B[N] = {};
B[i] = 1;
V.emplace_back(fromArray(B));
}
for (std::vector<int> & v : V)
{
for (int i : v)
{
std::cout << i << " ";
}
std::cout << "\n";
}
return 0;
}
Alternately, if you don't have all the Bs all in one go, just loop N times getting one B
If guessing, there is a my implementation:
int main() {
int len = 9;
int div = 3;
int total = len / div;
int B[len]={1, 0, 0, 0, 1, 0, 0, 0, 1};
vector<vector<int> > V(total);
int cnt = 0;
for (int i = 0; i < len && cnt < total; i += div) {
for (int j = i; j < i + div; j++) {
V[cnt].push_back(B[j]);
}cnt++;
}
for (int i = 0; i < total; i++) {
for (int j = 0; j < V[i].size(); j++) {
cout << V[i][j] << " ";
}cout << endl;
}
return 0;
}
V is like this:
1 0 0
0 1 0
0 0 1
You probably want this:
int main() {
const int Bsize = 9;
const int NumberOfLines = 4; // number of iterations
int B[Bsize] = { 1,2,3,4,5,6,7,8,9 };
vector<vector<int>> V;
V.resize(NumberOfLines);
int bIndex = 0;
for (int r = 0; r < NumberOfLines; r++) {
// add code that changes B here
V[r].resize(Bsize);
for (int w = 0; w < Bsize; w++) {
V[r][w] = B[w];
}
}
for (int m = 0; m < V.size(); m++) {
for (int k = 0; k < V[m].size(); k++) {
cout << " " << V[m][k];
}
cout << endl;
}
return 0;
}
In this sample we'll generate 4 lines (one for each iteration), but B is each time the same here. If you want B to change between each iteration, you need to insert the corresponding code that changes B.
The output of the sample will be:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9

Incorrect Result from Selection Sort Algorithm

#include <iostream>
using namespace std;
// Selection Sort function.
// Parameter 'a' is the size of the array.
void ss(int AR[] , int a) {
int small;
for (int i = 0 ; i <a ; i++) {
small = AR[i];
for (int j = i+1 ; j <a ; j++) {
if (AR[j]< small) {
int k = AR[j];
AR[j] = AR[i];
AR[i] = k;
}
}
}
}
int main() {
cout << "Enter the size of Your Aray";
int a;
cin >> a;
int AR[a];
cout << endl;
for (int i = 0; i < a; i++) {
cin >> AR[i];
cout << endl;
}
ss(AR, a);
cout << "The Sorted Array is";
for (int i=0; i < a; i++) {
cout << AR[i] << " ";
cout << endl;
}
}
When I enter the following:
15
6
13
22
23
52
2
The result returned is:
2
13
6
15
22
23
52
What is the bug preventing the list from being sorted numerically as expected?
The function can look like
void ss ( int a[], size_t n )
{
for ( size_t i = 0 ; i < n ; i++ )
{
size _t small = i;
for ( size_t j = i + 1; j < n ; j++ )
{
if ( a[j] < a[small] ) small = j;
}
if ( i != small )
{
int tmp = a[small];
a[small] = a[i];
a[i] = tmp;
}
}
}
It doesn't seem to be the SelectionSort I know. in the algorithm I know during every loop I look for the smallest element in the right subarray and than exchange it with the "pivot" element of the loop. Here's the algorithm
void selectionSort(int* a, int dim)
{
int posMin , aux;
for(int i = 0; i < dim - 1; ++i)
{
posMin = i;
for(int j = i + 1; j < dim; ++j)
{
if(a[j] < a[posMin])
posMin = j;
}
aux = a[i];
a[i] = a[posMin];
a[posMin] = aux;
}
}
and it seems that you change every smaller element you find, but also change the position of the "pivot". I hope the answer is clear.
Everything is ok in the original function, only that the small variable need to be refreshed when two vector elements will be switched.
Also in if statement set the small variable to the new value of AR[i].

Find a subarray of m*m (2<=m<n) having largest sum; out of an n*n int array(having +ve, -ve, 0s)

I have written a solution for the above problem but can someone please suggest an optimized way.
I have traversed through the array for count(2 to n) where count is finding subarrays of size count*count.
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] = {{1,2,3,4,5},{2,4,7,-2,1},{4,3,9,9,1},{5,2,6,8,0},{5,4,3,2,1}};
int max = 0;
int **tempStore, size;
for(int count = 2; count < n; count++)
{
for(int i = 0; i <= (n-count); i++)
{
for(int j = 0; j <= (n-count); j++)
{
int **temp = new int*[count];
for(int i = 0; i < count; ++i) {
temp[i] = new int[count];
}
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
temp[k][l] = a[i+k][j+l];
}
}
//printing fetched array
int sum = 0;
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
sum += temp[k][l];
cout<<temp[k][l]<<" ";
}cout<<endl;
}cout<<"Sum = "<<sum<<endl;
if(sum > max)
{
max = sum;
size = count;
tempStore = new int*[count];
for(int i = 0; i < count; ++i) {
tempStore[i] = new int[count];
}
//Locking the max sum array
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
tempStore[k][l] = temp[k][l];
}
}
}
//printing finished
cout<<"------------------\n";
//Clear temp memory
for(int i = 0; i < size; ++i) {
delete[] temp[i];
}
delete[] temp;
}
}
}
cout<<"Max sum is = "<<max<<endl;
for(int k = 0; k < size; k++)
{
for(int l = 0; l <size; l++)
{
cout<<tempStore[k][l]<<" ";
}cout<<endl;
}cout<<"-------------------------";
//Clear tempStore memory
for(int i = 0; i < size; ++i) {
delete[] tempStore[i];
}
delete[] tempStore;
Example:
1 2 3 4 5
2 4 7 -2 1
4 3 9 9 1
5 2 6 8 0
5 4 3 2 1
Output:
Max sum is = 71
2 4 7 -2
4 3 9 9
5 2 6 8
5 4 3 2
This is a problem best solved using Dynamic Programming (DP) or memoization.
Assuming n is significantly large, you will find that recalculating the sum of every possible combination of matrix will take too long, therefore if you could reuse previous calculations that would make everything much faster.
The idea is to start with the smaller matrices and calculate sum of the larger one reusing the precalculated value of the smaller ones.
long long *sub_solutions = new long long[n*n*m];
#define at(r,c,i) sub_solutions[((i)*n + (r))*n + (c)]
// Winner:
unsigned int w_row = 0, w_col = 0, w_size = 0;
// Fill first layer:
for ( int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
at(r, c, 0) = data[r][c];
if (data[r][c] > data[w_row][w_col]) {
w_row = r;
w_col = c;
}
}
}
// Fill remaining layers.
for ( int size = 1; size < m; size++) {
for ( int row = 0; row < n-size; row++) {
for (int col = 0; col < n-size; col++) {
long long sum = data[row+size][col+size];
for (int i = 0; i < size; i++) {
sum += data[row+size][col+i];
sum += data[row+i][col+size];
}
sum += at(row, col, size-1); // Reuse previous solution.
at(row, col, size) = sum;
if (sum > at(w_row, w_col, w_size)) { // Could optimize this part if you only need the sum.
w_row = row;
w_col = col;
w_size = size;
}
}
}
}
// The largest sum is of the sub_matrix starting a w_row, w_col, and has dimensions w_size+1.
long long largest = at(w_row, w_col, w_size);
delete [] sub_solutions;
This algorithm has complexity: O(n*n*m*m) or more precisely: 0.5*n*(n-1)*m*(m-1). (Now I haven't tested this so please let me know if there are any bugs.)
Try this one (using naive approach, will be easier to get the idea):
#include <iostream>
#include<vector>
using namespace std;
int main( )
{
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] =
{{2,1,8,9,0},{2,4,7,-2,1},{5,4,3,2,1},{3,4,9,9,2},{5,2,6,8,0}};
int sum, partsum;
int i, j, k, m;
sum = -999999; // presume minimum part sum
for (i = 0; i < n; i++) {
partsum = 0;
m = sizeof(a[i])/sizeof(int);
for (j = 0; j < m; j++) {
partsum += a[i][j];
}
if (partsum > sum) {
k = i;
sum = partsum;
}
}
// print subarray having largest sum
m = sizeof(a[k])/sizeof(int); // m needs to be recomputed
for (j = 0; j < m - 1; j++) {
cout << a[k][j] << ", ";
}
cout << a[k][m - 1] <<"\nmax part sum = " << sum << endl;
return 0;
}
With a cumulative sum, you may compute partial sum in constant time
std::vector<std::vector<int>>
compute_cumulative(const std::vector<std::vector<int>>& m)
{
std::vector<std::vector<int>> res(m.size() + 1, std::vector<int>(m.size() + 1));
for (std::size_t i = 0; i != m.size(); ++i) {
for (std::size_t j = 0; j != m.size(); ++j) {
res[i + 1][j + 1] = m[i][j] - res[i][j]
+ res[i + 1][j] + res[i][j + 1];
}
}
return res;
}
int compute_partial_sum(const std::vector<std::vector<int>>& cumulative, std::size_t i, std::size_t j, std::size_t size)
{
return cumulative[i][j] + cumulative[i + size][j + size]
- cumulative[i][j + size] - cumulative[i + size][j];
}
live example