Modifying iterator inside for loop - c++
I have a problem like this:
I got size of array and the array itself (all the elements) and i need to sort the array in the way that first item in array (lets call it key item) is placed so all items smaller then key item go left from key item and all items larger then key item go right form key item, but the items need to be i a same order as they was in declaration like so:
array input:
4 7 3 5 6 2 9 1 10 8
array output:
3 2 1 4 7 5 6 9 10 8
so i thought i can just go one time through array and if value is smaller then key item swap them and if value is larger then key item, place that value (item ) at the end (if there is n items in array place it on n+1 place) and then to shift all items from current index one place to the left like:
| 4 | 7 | 3 | 5 | 6 | 2 | 9 | 1 | 10 | 8 |
| 4 | | 3 | 5 | 6 | 2 | 9 | 1 | 10 | 8 | 7 |
| 4 | 3 | 5 | 6 | 2 | 9 | 1 | 10 | 8 | 7 |
but like that i would need to after every shifting make iterator stay same (so it can check that place again.
I have a code like this :
int u=1;
for (int i=1;i<n;i++){
if (x[i]<x[u]){
swap(x[i],x[u]);
u+=1;
}else {
x[i]=x[n];
for (int k=i;k<n-1;k++){x[k]=x[k+1];}
i--;
}
}
i think i made a mistake in the swapping part but i cant figure it out.
What you are looking for can be done using the STL's std::stable_partition() algorithm:
divides elements into two groups while preserving their relative order
Let it do the hard work for you, eg:
#include <iostream>
#include <algorithm>
struct doPartitionOn
{
int m_key;
doPartitionOn(int key) : m_key(key) {}
bool operator()(int a)
{
return (a < m_key);
}
};
int main()
{
int arr[] = {4, 7, 3, 5, 6, 2, 9, 1, 10, 8};
for(int i = 0; i < 10; ++i)
std::cout << arr[i] << ' ';
std::cout << std::endl;
std::stable_partition(arr, arr+10, doPartitionOn(arr[0]));
for(int i = 0; i < 10; ++i)
std::cout << arr[i] << ' ';
std::cout << std::endl;
std::cin.get();
return 0;
}
4 7 3 5 6 2 9 1 10 8
3 2 1 4 7 5 6 9 10 8
Live demo
Or, if using C++11 or later, you can use a lambda instead of a manual functor:
#include <iostream>
#include <algorithm>
int main()
{
int arr[] = {4, 7, 3, 5, 6, 2, 9, 1, 10, 8};
for(int value: arr)
std::cout << value << ' ';
std::cout << std::endl;
std::stable_partition(arr, arr+10, [&arr](int a){ return (a < arr[0]); });
for(int value: arr)
std::cout << value << ' ';
std::cout << std::endl;
std::cin.get();
return 0;
}
4 7 3 5 6 2 9 1 10 8
3 2 1 4 7 5 6 9 10 8
Live demo
Related
C++ decrementing the iterator
I'm new to C++ and currently learning iterators. I wrote the following code, which adds the first and last digit in a vector. In order to decrement the iterator, I've had to decrement the variable dec_pointer twice for the correct results. I'm obviously doing something wrong, but what? #include <iostream> #include <vector> #include <string> int main() { std::vector<int> vec{1,4,2,6,9,10,17,13,15}; size_t first_last =0; size_t dec_pointer = vec.size()-1; for(auto it =vec.cbegin(); it !=vec.cend() && !vec.empty(); ++it) { first_last = *it + *(it+(dec_pointer--)); std::cout<<"Add First and Last Digit : "<<first_last<<std::endl; dec_pointer--; } return 0; }
If you were adding the first and last elements (as per your text), you wouldn't need a loop, you could just do (after checking minimum size, of course): first_plus_last = *(vec.cbegin()) + *(vec.cend()-1); It looks however that you're trying to add the first and last, second and second last, and so on. The reason why you would have to decrement twice is because you're getting the second iterator value by adding something to the current iterator value (not the start iterator). For example, let's for the purposes of understanding just pretend they're indexes rather than iterators: index: 0 1 2 3 4 5 6 7 8 value: 1 4 2 6 9 10 17 13 15 To correctly add the first (moving) index and a delta value to get the second index, you would need: index1 index2 index2 as (index1 + delta) ------ ------ -------------------------- 0 8 0 + 8 1 7 1 + 6 2 6 2 + 4 ... and so on You can see that the required delta is decreasing by two each time: 8, 6, 4, .... But, rather than doing iterator calculations, I would opt for just running an iterator from both ends, toward the middle. In other words, something like this: #include <iostream> #include <vector> int main() { std::vector<int> vec{1, 4, 2, 6, 9, 10, 17, 13, 15}; if (vec.size() > 0) { auto left = vec.cbegin(); auto right = vec.cend() - 1; while (left < right) { auto num1 = *left++; auto num2 = *right--; auto sum = num1 + num2; std::cout << "Add (" << num1 << ", " << num2 << "): " << sum << '\n'; } if (left == right) { std::cout << "One number left in middle: " << *left << '\n'; } } } That seems like cleaner (as in "easier to understand") code to me, and the output is: Add (1, 15): 16 Add (4, 13): 17 Add (2, 17): 19 Add (6, 10): 16 One number left in middle: 9 It also works with all the possible vector sizes (empty, one element, even number of elements, and odd number of elements greater than one).
If you used vec.cbegin() instead of it when calculating the last pointer, you would not have this issue. first_last = *it + *(vec.cbegin() + dec_pointer--)
On the 1st loop iteration, it refers to the first element, and dec_pointer is 8, so you have: ----------------------------------------- | 1 | 4 | 2 | 6 | 9 | 10 | 17 | 13 | 15 | ----------------------------------------- ^ ^ it it+8 If you then increment it by 1 and decrement dec_pointer by 1 not 2, on the 2nd iteration dec_pointer is now 7 and you have this: ----------------------------------------- | 1 | 4 | 2 | 6 | 9 | 10 | 17 | 13 | 15 | ----------------------------------------- ^ ^ it it+7 If you then increment it by 1 and decrement dec_pointer by 1 not 2, on the 3rd iteration dec_pointer is now 6 and you have this: ----------------------------------------- | 1 | 4 | 2 | 6 | 9 | 10 | 17 | 13 | 15 | ----------------------------------------- ^ ^ it it+6 And so on. So, as you can see, the last value you refer to with it+dec_pointer is always the same element 15. That is why you have to decrement dec_pointer by 2 instead of 1 to get the correct result: ----------------------------------------- | 1 | 4 | 2 | 6 | 9 | 10 | 17 | 13 | 15 | ----------------------------------------- ^ ^ ^ ^ ^ ^ it | | | | it+8 | | | | it+1 | | (it+1)+6 | | it+2 (it+2)+4 That being said, I would suggest an alternative and simpler solution - use a reverse_iterator from vec.crbegin() to access the 2nd value, instead of offsetting a forward iterator from vec.cbegin(), eg: #include <iostream> #include <vector> #include <string> int main() { std::vector<int> vec{1,4,2,6,9,10,17,13,15}; auto last_it = vec.crbegin(); for(auto it = vec.cbegin(); it != vec.cend(); ++it, ++last_it) { int first_last = *it + *last_it; std::cout << "Add First and Last Digit : " << first_last << std::endl; } return 0; } Online Demo Or even simpler, just get rid of the it loop iterator completely: #include <iostream> #include <vector> #include <string> int main() { std::vector<int> vec{1,4,2,6,9,10,17,13,15}; auto last_it = vec.crbegin(); for(int first : vec) { int first_last = first + *last_it++; std::cout << "Add First and Last Digit : " << first_last << std::endl; } return 0; } Online Demo
How to relocate an element in one array in C++
I took this interview question and I failed, so I'm here to not fail again! I have an array of int with size 16 and a 5 < givenIndex < 10. I have to take the element in this index a print every possible array (there are 16) by moving the element at givenIndex through every position in array and pushing rest of elements. For example: int array[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; int givenIndex = 6; Since array[givenIndex] = 7, I need to move 7 to every possible position and print that array. [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16] And that's for 16 cases. What I was trying was: for(int i = 0;i<16;i++){ array[i] = array[indexInsercion] if (i<indexInsert){ //right shift array[i] = array[i+1] }else if(i == indexInsert){ //no shift }else{ //left shift array[i] = array[i-1] } } Can I get some help?
We can only guess what the interviewer expected to see. If I was the interviewer I would like to see that you keep things simple. This is code I think one can expect to be written from scratch in an interview situation: #include <iostream> #include <array> template <size_t size> void print_replaced(const std::array<int,size>& x,size_t index){ for (int i=0;i<size;++i){ for (int j=0;j<i;++j) { if (j == index) continue; std::cout << x[j] << " "; } std::cout << x[index] << " "; for (int j=i;j<size;++j) { if (j == index) continue; std::cout << x[j] << " "; } std::cout << "\n"; } } int main() { std::array<int,16> x{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; print_replaced(x,6); } It is a first approach at the problem, with a loop that prints 16 different combinations of the array elements. Printing each line follows simple logic: We print all elements before the one that should be replaced, then the one that should be shuffled, then the remaining elements. It is simple, but wrong. Its output is: 7 1 2 3 4 5 6 8 9 10 11 12 13 14 15 16 1 7 2 3 4 5 6 8 9 10 11 12 13 14 15 16 1 2 7 3 4 5 6 8 9 10 11 12 13 14 15 16 1 2 3 7 4 5 6 8 9 10 11 12 13 14 15 16 1 2 3 4 7 5 6 8 9 10 11 12 13 14 15 16 1 2 3 4 5 7 6 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 8 7 9 10 11 12 13 14 15 16 1 2 3 4 5 6 8 9 7 10 11 12 13 14 15 16 1 2 3 4 5 6 8 9 10 7 11 12 13 14 15 16 1 2 3 4 5 6 8 9 10 11 7 12 13 14 15 16 1 2 3 4 5 6 8 9 10 11 12 7 13 14 15 16 1 2 3 4 5 6 8 9 10 11 12 13 7 14 15 16 1 2 3 4 5 6 8 9 10 11 12 13 14 7 15 16 1 2 3 4 5 6 8 9 10 11 12 13 14 15 7 16 There is one line that appears twice and the last line is missing. As an interviewer I would not be surprised that the first attempt does not produce correct output. I don't care about that. Thats not a minus. What I would care about is how you react on that. Do you know the next steps? Do you have a strategy to fix the wrong output? Or do you just panic because you didn't manage to write the correct code on the first attempt? This is what I would like to check in an interview and then thats the end of the exercise. I want to ask more different questions rather than giving you the time to fix all mistakes and write correct well tested code, because I know that this takes more time than we have in the interview. I'll leave it to you to fix the above code ;)
Here's a quick stab at it. Basically just keep track of where the given index should go and print it there as well as skip the original position it would be in. #include <iostream> int main() { int array[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; int givenIndex = 6; for (int p = 0; p <= 16; ++p) { if (p != givenIndex) { std::cout << "["; for (int i = 0; i < 16; ++i) { if (i == p) { if (i > 0) { std::cout << ","; } std::cout << array[givenIndex]; } if (array[i] != array[givenIndex]) { if (i > 0 || p == 0) { std::cout << ","; } std::cout << array[i]; } } if (p == 16) { std::cout << "," << array[givenIndex]; } std::cout << "]\n"; } } } Output: [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16] [1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16] [1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] [1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16] [1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16] [1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16] [1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16] [1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16] [1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16] [1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7]
If the expectation is to just print the elements of array in the given order: Keep the track of current index of array element to be print, say indx - If the position of current element processing is equal to row number then print the element at givenIndex. If indx is equal to givenIndex skip it and print indx + 1 element, otherwise print element at indx and increase indx by 1. Implementation: #include <iostream> #include <array> int main() { std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; std::size_t givenIndex = 6; for (std::size_t i = 0, indx = 0; i < array.size(); indx = 0, ++i) { std::cout << '['; for (std::size_t j = 0; j < array.size(); ++j) { if (j == i) { std::cout << array[givenIndex] << ','; continue; } if (indx == givenIndex) { ++indx; } std::cout << array[indx++] << ','; } std::cout << ']'; std::cout << '\n'; } return 0; } Output: # ./a.out [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,] If the expectation is to alter the order of elements in the array and then print the array: First move the element at givenIndex to the 0th index of array and then - Print array In every iteration swap the current element with its next element in the array and print it. Implementation: #include <iostream> #include <array> void print_array (std::array<int, 16>& array) { std::cout << '['; for (std::size_t indx = 0; indx < array.size(); ++indx) { std::cout << array[indx] << ','; } std::cout << ']'; std::cout << '\n'; } void rearrange_array_elem (std::array<int, 16>& array, std::size_t givenIndx) { // move the element at givneIndx to first position in array for (std::size_t j = givenIndx; j > 0; --j) { std::swap (array[j], array[j - 1]); } // print array print_array (array); for (std::size_t indx = 0; indx < array.size() - 1; ++indx) { // swap current element with its next element std::swap (array[indx], array[indx + 1]); print_array (array); } } int main() { std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; std::size_t givenIndex = 6; rearrange_array_elem (array, givenIndex); return 0; } Output: # ./a.out [7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,] [1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,]
Code for counting frequency of element in array not working
I'm trying to find the frequency of elements in an array. I have found lots of programs on Google that can do just this, but I can't get them to count right for my array. This is the code I use: #include <iostrem> #include <cmath> const int nmax = 50; int main() { int afk[nmax], count; const int N = 40; int dn[N] = { 6, 1, 2, 1, 5, 3, 1, 0, 3, 1, 2, 3, 6, 2, 1, 1, 5, 5, 1, 5, 0, 1, 3, 0, 0, 1, 0, 2, 1, 0, 0, 3, 1, 5, 2, 1, 4, 1, 0, 3 }; for (int i = 0; i < N; i++) { afk[i] = -1; } for (int i = 0; i < N; i++) { count = 1; for (int j = i + 1; j < N; j++) { if (dn[i] == dn[j]) { count++; afk[j] = 0; } } if (afk[i] != 0) afk[i] = count; } for (int i = 0; i <= 6; i++) { if (afk[i] != 0) { cout << endl << i << " | " << afk[i]; } } } This gives the output: 0 | 2 1 | 13 2 | 5 4 | 5 5 | 6 But I know this is worng and the right answer is 0 | 8 1 | 13 2 | 5 3 | 6 4 | 1 5 | 5 6 | 2 So the code only gets the frequency of elemnet 1 and 2 right. Can anyone tell what's wrong with this code?
You are counting the frequencies just fine (well, not as efficiently as you could be), but you are not displaying them correctly. The afk[] array is storing each number's frequency at the same index as its first occurrence in the dn[] array. In your final display loop, you are printing the loop counter i itself instead of printing the number at the i'th index of the dn[] array. So, if you change this: cout << endl << i << " | " << afk[i]; To this: cout << endl << dn[i] << " | " << afk[i]; Then you will get a more meaningful result: 6 | 2 1 | 13 2 | 5 5 | 5 3 | 6 Note that the frequencies of 0 and 4 are missing, though. The first occurrence of 0 in the dn[] array is at index 7, and the first occurrence of 4 is at index 36. But your display loop stops after index 6, which is why it does not display the frequencies of 0 and 4. You would need to loop over the entire afk[] array to fix that, then you will see the missing entries: 6 | 2 1 | 13 2 | 5 5 | 5 3 | 6 0 | 8 4 | 1 Demo However, the results are not sorted by number, as you want. To fix that, you will have to either: sort the dn[] array before counting its frequencies (which, incidentally, will help make counting easier). change the afk[] array to hold a struct type that contains int number and int frequency members, and then you can sort afk[] on number after counting the frequencies. if nmax is greater than the largest number in the dn[] array (ie, > 6 in this case), then your counting loop can simply use the number stored at dn[i] as the index into afk[] rather than using i as the index. Then your display loop can simply display the afk[] array as-is (I suspect this is what you originally meant to do). Demo In which case, it would be far easier to count the frequencies using a std::map instead, and let it handle the counting and sorting for you, eg: #include <iostream> #include <map> using namespace std; int main() { map<int, int> afk; int dn[40] = {6, 1, 2, 1, 5, 3, 1, 0, 3, 1, 2, 3, 6, 2, 1, 1, 5, 5, 1, 5, 0, 1, 3, 0, 0, 1, 0, 2, 1, 0, 0, 3, 1, 5, 2, 1, 4, 1, 0, 3}; for(auto number : dn){ afk[number]++; } for(auto &p : afk){ cout << p.first << " | " << p.second << endl; } } 0 | 8 1 | 13 2 | 5 3 | 6 4 | 1 5 | 5 6 | 2 Demo
Splitting std::vector of size m into vector of vectors of size n
Given a vector [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], what are some possible approaches to construct [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17]], focusing primarily on readability? At the moment, I have correctly defined the starting and ending indexes of all the subarrays, and was trying to use std::copy(cam.begin() + start, cam.begin() + end+ 1, vec.begin()); to construct a new vector.. resulting in: terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
If you're just after some code that can split a vector into a vector of up-to-five-element vectors, this should do it. It's bigger than necessary only because of the test harness around it. The "meat" of the code is the templated function makeVecOfVecs(), and the single-line call to it. It's quite handy to do this sort of thing as a template since it then becomes easy to extend to other data types. The code is: #include <iostream> #include <vector> // From a flat vector, construct a vector of sub-vectors, each of a // specific size (except the last sub-vector, which may be smaller). template<class T> std::vector<std::vector<T>> makeVecOfVecs( const std::vector<T> &in, unsigned int sz ) { std::vector<std::vector<T>> out; for (int i = 0; i < in.size(); i += sz) { if (in.size() - i < sz) sz = in.size() - i; std::vector<T> newVec(sz); std::copy(in.begin() + i, in.begin() + i + sz, newVec.begin()); out.push_back(newVec); // As pointed out in a comment, you could probably // replace the three preceding lines with just: // out.emplace_back(in.begin() + i, in.begin() + i + sz); // and avoid creating newVec. } return out; } // Test harness for the above function. int main(int argc, char *argv[]) { // Default to 17 values, allow for override. Could probably // make more robust, but is IS only test code. int count = 17; if (argc > 1) count = atoi(argv[1]); // Input data for testing, print for validation. std::vector<int> in; for (int i = 0; i < count; ++i) in.push_back(i + 1); std::cout << "\nInput (" << count << "):"; for (const auto &inElem: in) std::cout << " " << inElem; std::cout << "\n"; auto out = makeVecOfVecs<int>(in, 5); // Output of result for validation. std::cout << "Output:\n"; for (const auto &outElem1: out) { std::cout << " "; for (const auto &outElem2: outElem1) std::cout << " " << outElem2; std::cout << "\n"; } } A few sample runs are shown below for validation (you'll see I've asked for a chunk size of 10 rather than 5, that's just to use less space in the answer): pax:~> for i in "" 22 20 0 -9 1; do ./testprog ${i}; done Input (17): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Output: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Input (22): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Output: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Input (20): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Output: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Input (0): Output: Input (-9): Output: Input (1): 1 Output: 1
If the vector of vectors is interpreted as a matrix, the first n-1 rows can be filled in a straightforward way by copying segments from the one-dimensional input vector. Only the last row of that "matrix" requires some attention, as it may not be completely filled. #include <iostream> #include <algorithm> #include <vector> #include <numeric> #include <cmath> int main() { // create initial data int vecSize = 17; std::vector<int> inVec(vecSize); std::iota(inVec.begin(), inVec.end(), 1); // prepare new container int ncol = 5; int nrow = std::ceil(float(vecSize) / float(ncol)); std::vector<std::vector<int>> outVecVec(nrow); // row-wise copy for (int i = 0; i < nrow; ++i) { int rowLength = ncol; if (i == nrow - 1 && vecSize % ncol != 0) { rowLength = vecSize % ncol; // length of last row, if not filled } outVecVec[i].resize(rowLength); auto vecIndex = inVec.begin() + i * ncol; std::copy(vecIndex, vecIndex + rowLength, outVecVec[i].begin()); } // print output for (int i = 0; i < nrow; ++i) { for (int j = 0; j < outVecVec[i].size(); ++j) std::cout << outVecVec[i][j] << " "; std::cout << std::endl; } } demo: https://godbolt.org/z/w9aDrE
Using the range-v3 library this becomes very simple, and readable: std::vector<int> v = ... int m = ... auto vs = v | ranges::views::chunk(m) | ranges::to<std::vector<std::vector<int>>>; Here's a demo.
How to output horizontal letters in an array table
I am making a 6x6 dice game and I need to be able to put ROWS on the y-axis of the table but I do not understand how to do that with my code. Create a 6x6 2D-Table that holds the sum of the rows and columns using values 1 to 6. I have been reading through the ninth edition of "Starting out with C++ From Control Structures through Objects" by Tony Gaddis and I just cannot find anything about what I am looking for. //System Libraries #include <iostream> //Input/Output Library #include <iomanip> //Format Library using namespace std; //User Libraries //Global Constants, no Global Variables are allowed //Math/Physics/Conversions/Higher Dimensions - i.e. PI, e, etc... const int COLS=7; //Function Prototypes void fillTbl(int [][COLS],int); void prntTbl(const int [][COLS],int); //Execution Begins Here! int main(int argc, char** argv) { //Declare Variables const int ROWS=6; int tablSum[ROWS][COLS] ={{1,2,3,4,5,6,7}, {2,3,4,5,6,7,8}, {3,4,5,6,7,8,9}, {4,5,6,7,8,9,10}, {5,6,7,8,9,10,11}, {6,7,8,9,10,11,12}}; //Initialize or input i.e. set variable values fillTbl(tablSum,ROWS); cout<<"Think of this as the Sum of Dice Table\n"; cout<<" C o l u m n s\n"; cout<<" | 1 2 3 4 5 6\n"; cout<<"----------------------------------\n"; //Display the outputs prntTbl(tablSum,ROWS); //Exit stage right or left! return 0; } void fillTbl(int tablSum [][COLS],int ROWS) { cout<<""; } void prntTbl(const int tablSum [][COLS],int ROWS) { for(int x = 0; x < ROWS; x++) { for(int y = 0; y < COLS; y++) { cout<<setw(4)<<tablSum[x][y]; } cout<<endl; } } Your Output Think·of·this·as·the·Sum·of·Dice·Table↵ ···········C·o·l·u·m·n·s↵ ·····|···1···2···3···4···5···6↵ ----------------------------------↵ ···1···2···3···4···5···6···7↵ ···2···3···4···5···6···7···8↵ ···3···4···5···6···7···8···9↵ ···4···5···6···7···8···9··10↵ ···5···6···7···8···9··10··11↵ ···6···7···8···9··10··11··12↵ Expected Output Think·of·this·as·the·Sum·of·Dice·Table↵ ···········C·o·l·u·m·n·s↵ ·····|···1···2···3···4···5···6↵ ----------------------------------↵ ···1·|···2···3···4···5···6···7↵ R··2·|···3···4···5···6···7···8↵ O··3·|···4···5···6···7···8···9↵ W··4·|···5···6···7···8···9··10↵ S··5·|···6···7···8···9··10··11↵ ···6·|···7···8···9··10··11··12↵
We can change your prntTbl function to have a string literal containing the rows string with: char* rows = " ROWS "; Then before every inner loop iteration, we can print the character at the index of the string using our first loop index, as well as the row value and any spacing using: cout << rows[x] << " " << x + 1 << " |"; Our ending prntTbl method looks like: void prntTbl(const int tablSum [][COLS],int ROWS) { char* rows = " ROWS "; for(int x = 0; x < ROWS; x++) { cout << rows[x] << " " << x + 1 << " |"; for(int y = 0; y < COLS; y++) { cout<<setw(4)<<tablSum[x][y]; } cout<<endl; } and the output: C o l u m n s | 1 2 3 4 5 6 ---------------------------------- 1 | 1 2 3 4 5 6 7 R 2 | 2 3 4 5 6 7 8 O 3 | 3 4 5 6 7 8 9 W 4 | 4 5 6 7 8 9 10 S 5 | 5 6 7 8 9 10 11 6 | 6 7 8 9 10 11 12