Reputation: 2441
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;
}
output: 33 33 33 33 33 33 2 = 200
Upvotes: 0
Views: 4460
Reputation: 1179
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
Upvotes: 0
Reputation: 24185
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;
}
}
Upvotes: 1