How to write multiple vectors to multidimensional array? - c++

I have 2 vectors of ints:
vector<int> even = {2, 4, 6, 8};
vector<int> odd = {1, 3, 5, 7, 9};
I am trying to pass these vectors into a 2d array so that they end up looking like this:
array[2][5] = {2, 4, 6, 8,
1, 3, 5, 7, 9};
Writing a function to do this but I cant get it to work, this is the code so far:
void copy(vector<int> even, vector<int> odd,int arr[][COLMAX]){
int vectors = 2;
for(int row = 0; row < vectors; row++){
for(int col = 0; col < even.size(); col++){
arr[row][col] = even[col];
}
cout << endl;
}
}
Edit: Added function code

Here is one way:
void copy(vector<int> even, vector<int> odd,int arr[][COLMAX]){
for(int col = 0; col < even.size(); col++){
arr[0][col] = even[col];
}
for(int col = 0; col < odd.size(); col++){
arr[1][col] = odd[col];
}
}

Why go for arrays if you can use vectors?
If you can use a 2D vector instead of a 2D array, you'd have much more flexibility. And it'll be very simple:
vector<int> even = {2, 4, 6, 8};
vector<int> odd = {1, 3, 5, 7, 9};
vector<vector<int>> v {even,odd}; // that's sufficient !!
for (auto &r: v) { // and this is only the printing of the results
std::copy(r.cbegin(), r.cend(), ostream_iterator<int>(cout," "));
cout <<endl;
}
If you must really use raw arrays...
Now if you really want to use fixed size 2D arrays, you can update your function:
const size_t COLMAX=10;
void mycopy(vector<int> even, vector<int> odd,int arr[][COLMAX]){
vector<const vector<int> *>v ={&even,&odd};
for(int row=0; row<v.size(); row++) {
for(int col = 0; col <COLMAX; col++){
arr[row][col] = (col < v[row]->size() ? (*v[row])[col]:0);
}
}
}
It uses a pointer to the vectors to avoid repeating several time the same code for the different vectors. Moreover, you could easily make it work for 3 or 4 vecotrs (and with a little imagination you could eaily adapt it for a variable number of arguments).
You can then use it as planned:
int myarr[2][COLMAX];
mycopy (even, odd, myarr);
for (int i=0; i<2; i++) {
std::copy (myarr[i], myarr[i]+COLMAX, ostream_iterator<int>(cout," "));
cout <<endl;
}
The problem is that you do not keep track of the number of elements that are really in each line, so you'd have either al lot of truncated lines, or lines with a lot of trailing zeroes.

Related

How to store values from a normal array to a 2D array in C++?

I want to store the Values to the CustomValues array. How can I do this?
Any code and explanation would be great.
int main() {
int CustomValues[4][3];
int Values[3] = {234, 98, 0};
int Values1[3] = {21, 34, 5};
int Values2[3] = { 12, 6, 765 };
int Values3[3] = { 54, 67, 76 };
}
The CustomValues array should look like:
{{234, 98, 0}, { 21, 34, 5 }, { 12, 6, 765 }, { 54, 67, 76 }}
There's a few different ways you can do this. Since we already know your constraints, I've taken liberties to not do this dynamically.
The first is memcpy, which is in the <cstring> header:
memcpy(CustomValues[0], Values, sizeof(Values));
memcpy(CustomValues[1], Values1, sizeof(Values1));
memcpy(CustomValues[2], Values2, sizeof(Values2));
memcpy(CustomValues[3], Values3, sizeof(Values3));
Another is to loop through the array and store the values individually:
for (int i = 0; i < sizeof(CustomValues)/sizeof(CustomValues[0]); i++) {
for (int j = 0; j < sizeof(CustomValues[0])/sizeof(CustomValues[0][0]); j++) {
if (i == 0) {
CustomValues[i][j] = Values[j];
}
else if (i == 1) {
CustomValues[i][j] = Values1[j];
}
else if (i == 2) {
CustomValues[i][j] = Values2[j];
}
else if (i == 3) {
CustomValues[i][j] = Values3[j];
}
}
}
There is probably a better way to handle the logic for selecting which Values array you want, but that was just a quick solution to demonstrate.
EDIT: Example of 2D Vector usage
This example doesn't contain the logic for actually controlling the number of elements in a vector, but you can simply do that by following the for loop logic. Basically, you just need something to check the size of your vector with size(), and then move to a different one.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<vector<int>> CustomValues; //2D vector
//1D vectors
vector<int> Values;
vector<int> Values1;
Values.push_back(234); //to insert a value individually
Values.insert(Values.end(), {98, 0}); //to append multiple values
Values1.insert(Values1.end(), {21, 34, 5});
//inserting the 1D arrays to the 2D arrays
CustomValues.push_back(Values);
CustomValues.push_back(Values1);
//example of getting # of elements
int countOfInnerVectors = 0;
for (int i = 0; i < CustomValues.size(); i++)
countOfInnerVectors++;
cout << "The number of 1D vectors in CustomValues is: " << countOfInnerVectors;
}
An example of checking for the correct amount of vectors would be:
//check if we have less than 10 inner vectors
int maxCustomValuesSize = 10;
if (CustomValues2.size() < maxCustomValuesSize)
In this example, you would have something like int index = 0, and when that if is no longer satisfied, you could do index++ or some other logic to start inserts at your new index, like CustomValues2[index].push_back(Values);.
You can follow the same logic for the inner vectors as well, you would just be changing to a new 1D array instead of changing to a new "row" like the outer vector does.

How to safely insert an element into an array c++?

I have a simple program to add an element to an array:
void printArray(int inp[], int size)
{
cout << "[";
for (int i = 0; i < size - 1; i++)
{
cout << inp[i] << ", ";
}
cout << inp[size - 1] << "]" << endl;
}
int addElement(int inputArray[], int inputSize, int element, int atIndex)
{
int cur = inputSize;
while (cur >= 0)
{
if (cur == atIndex)
{
inputArray[cur] = element;
return inputSize + 1;
}
inputArray[cur] = inputArray[cur - 1];
cur--;
}
return inputSize + 1;
}
int arr1[] = {1, 5, 9, 2};
int arr2[] = {1, 5, 9, 2};
int main()
{
int arraySize = sizeof(arr1) / sizeof(arr1[0]);
addElement(arr1, arraySize, 7, 0);
printArray(arr1, arraySize + 1);
printArray(arr2, arraySize);
return 0;
}
This outputs:
[7, 1, 5, 9, 2] [2, 5, 9, 2]
Even though I haven't touched arr2 it is modified. I think because arr1 and arr2 are allocated contiguously in memory, and naively adding an element to arr1 overwrites arr2[0].
How should I handle this case and add only if the next space is unused, otherwise move the entire array to another location?
You can achieve this easily by using std::vector.
It has a method called insert, where you just pass a position and a number as arguments and it will handle the reallocation by itself.
For example: if you write:
vector<int> vec = { 1, 2, 3, 4, 5 };
vec.insert(vec.begin() + 2, 100);
Now elements in your vector are 1, 2, 100, 3, 4, 5.
I don't know if this will help you, but you can also add multiple elements at once:
vector<int> vec = { 1, 2, 3, 4, 5 };
vec.insert(vec.begin() + 3, { 100, 101 });
Now elements in your vector are: 1, 2, 3, 100, 101, 4, 5.
As you can see, the first argument is the position of the first inserted element and the second one is element or list of elements that you want to insert.
You can read more about std::vector here and about std::vector::insert here
Hope this helps.
As what the comments mentioned by #StoryTeller, you can use a std::vector.
But you have to pick on which function of the container you wanna use, there are 2 types.
::insert, which inserts data on the specific location in the
container. This is iterator based.
::push_back, which inserts at the back/last of the container
You can use any of them, depending on your purpose, just be sure of ::insert that you are pointing to the correct position(iterator wise).
Also, as of C++11 you can use ::emplace and ::emplace_back, which constructs and inserts data. You can find more at,
http://www.cplusplus.com/reference/vector/vector/
Hope this helps.
I have a simple program to add an element to an array:
Impossible. An array's size is fixed at compile time. In other words,
int arr1[] = {1, 5, 9, 2};
is a lot like:
int arr1_1 = 1;
int arr1_2 = 5;
int arr1_3 = 9;
int arr1_4 = 2;
I think it is helpful, for learning purposes, to view an array like this, and not like a container which can shrink and grow while the program is running. Adding an element to an array at runtime would be like asking to add a variable at runtime. C++ arrays don't work like that.
You can use new[] to set an array's initial size at runtime, but even then you cannot "add" anything. In fact, don't use new[], ever.
Go to cppreference.com, learn about std::vector and relearn everything from scratch. Start with the example code at the bottom of the page.

C++ insertion sorting elements

Other way for elements to be in function instead of main program?
void insertionSort(int array[], int number)
{
int j, temp;
for (int i = 1; i<number; i++)
{
j = i;
while (j>0 && array[j - 1]>array[j])
{
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
j--;
}
}
}
int main()
{
int number = 8;
int array[] = { 2, 7, 5, 6, 4, 8, 1, 3 };
insertionSort(array, 8);
for (int i = 0; i<number; i++)
cout << array[i] << " ";
cout << endl;
system("PAUSE");
return 0;
}
While the data to be sorted could be moved into the sort function, doing so creates a function that's pretty much useless--since it only ever sorts one set of data, it's equivalent to return {1, 2, 3, 4 5, 6, 7, 8};
Your insertion sort is also a bit of a mess. Pseudo-code for an insertion sort normally looks something like this:
for i in 1 to size do
temp = array[i]
for j in i downto 0 and array[j-1] > temp do
array[j] = array[j-1]
array[j] = temp
I would suggest that you do not do this. A function is supposed to be a reusable piece of code. If you hardcode the array into the function then that function could only ever sort the array that is in the function and you would have to edit the array in the function to sort something different. By passing the array to the function now you have the ability to pass any array to the function and it will get sorted. You could even call the function multiple times with different arrays in the same program and they will be sorted.
I will also mention that if you move the array to be in the sort function then it won't be in main() and you won't be able to print out the array in main() as you have it now.

How to pass 1 column of a 2D matrix to a function in C/C++

I have a 2D C-style array from which I have to pass just one column of it to a function. How do I do that?
Basically I need the C/C++ equivalent of the MATLAB command A[:,j] which would give me a column vector. Is it possible in C/C++?
You have 3 options,
1) Pass a pointer to your object (after moving it to the first element of the destination column)
twoDArray[0][column]
Now you can calculate the next item for this column (by jumping through the elements)
2) Create a wrapper class that would do this for you.
custom2DArray->getCol(1);
.
.
.
class YourWrapper{
private:
auto array = new int[10][10];
public:
vector<int> getCol(int col);
}
YourWrapper:: vector<int> getCol(int col){
//iterate your 2d array(like in option 1) and insert values
//in the vector and return
}
3) Use a 1d array instead. You can get this info easily. By jumping through rows and accessing the value for the desired column.(Mentioning just for the sake of mentioning, don't hold it against me)
int colsum(int *a, int rows, int col)
{
int i;
int sum = 0;
for (i = 0; i < rows; i++)
{
sum += *(a + i*rows+col);
}
return sum;
}
int _tmain(int argc, _TCHAR* argv[])
{
int rows = 2;
int cols = 2;
int i, j;
int *a;
a = (int*)malloc(rows*cols*sizeof(int));
// This just fills each element of the array with it's column number.
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
*(a+i*rows + j) = j;
}
}
// Returns the sum of all elements in column 1 (second from left)
int q = colsum(a, rows, 1);
printf("%i\n", q);
return 0;
}
It's not exactly passing the column, it's passing a pointer to the beginning of the array and then giving it instructions on how many rows the array has and which column to concern itself with.
considering your 2d array:
std::vector<std::vector<int> > *array = new std::vector<std::vector<int> >;
std::list myCol;
... //fill your array
//Here we iterate through each row with an iterator
for (auto it = array->begin(); it != array->end(); ++it)
//Then we access the value of one col of this row
myCol.push_back(it[col]);
//MyCol will be filled with the col values
for col = 1, myCol=[8, 3, 1, 4]
\/
it->[[2, 8, 4, 3],
\/ [6, 3, 9, 6],
[9, 1, 3, 3],
[2, 4, 2, 7]]

Convert a std::vector<std::vector <double> > representing a 2D array to cv::Mat

What is the most elegant and efficient way to convert a nested std::vector of std::vectors to cv::Mat? The nested structure is holding an array, i.e. all the inner std::vectors have the same size and represent matrix rows. I don't mind the data being copied from one to another.
I know that a single, non-nested std::vector is very easy, there is a constructor:
std::vector <double> myvec;
cv::Mat mymat;
// fill myvec
bool copy = true;
myMat = cv::Mat(myvec, copy);
What about the nested vector?
My variant (requires OpenCV 2.4):
int size = 5;
vector<vector<double> > w(size);
for(int i = 0; i < size; ++i)
{
w[i].resize(size);
for(int j = 0; j < size; ++j)
w[i][j] = (i+1) * 10 + j;
}
Mat m(size, size, CV_64F);
for(int i = 0; i < w.size(); ++i)
m.row(i) = Mat(w[i]).t();
cout << m << endl;
Outputs:
[10, 11, 12, 13, 14;
20, 21, 22, 23, 24;
30, 31, 32, 33, 34;
40, 41, 42, 43, 44;
50, 51, 52, 53, 54]
Explanation of m.row(i) = Mat(w[i]).t():
m.row(i) sets the ROI, it points to original matrix
Mat(w[i]) wraps vector without data copying
.t() creates "matrix expression" - no data copying performed
= evaluates matrix expression but because vector is wrapped into the (size x 1) continuous matrix it is evaluated without real transpose with a single call to memcpy.
This is a way to do it:
std::vector<double> row1;
row1.push_back(1.0); row1.push_back(2.0); row1.push_back(3.0);
std::vector<double> row2;
row2.push_back(4.0); row2.push_back(5.0); row2.push_back(6.0);
std::vector<std::vector<double> > vector_of_rows;
vector_of_rows.push_back(row1);
vector_of_rows.push_back(row2);
// make sure the size of of row1 and row2 are the same, else you'll have serious problems!
cv::Mat my_mat(vector_of_rows.size(), row1.size(), CV_64F);
for (size_t i = 0; i < vector_of_rows.size(); i++)
{
for (size_t j = 0; j < row1.size(); j++)
{
my_mat.at<double>(i,j) = vector_of_rows[i][j];
}
}
std::cout << my_mat << std::endl;
Outputs:
[1, 2, 3;
4, 5, 6]
I tried another approach using the constructor of Mat and the push_back() method but without success, maybe you can figure it out. Good luck!