Isolate a column of a vector in c++ - c++

I have a 2d vector of string and need to isolate out three of the columns into 3 separate 1d arrays so i can convert them to doubles and perform operations on them.
Simply using:
for (int i = 0; i < 100; i++)
{
vectorname[i][2] = arrayname[i];
}
doesn't work and I don't understand why.
Sorry im new to coding and thanks in advance.
Thanks to first reply, i don't care if i remove the data or not, i just need it so i can operate on it, my vectors are declared as:
string vectorname[101][5];
string arrayname[99];
string arrayname2[99];
string arrayname3[99];
Ok I dont have my vectorname defined as a vector, it's just a 2d string, can i extract a column from that?

Do the columns still need to remain in the 2D vector, or be pulled out completely as independent data?
If you need independent data, I would do
vector<double> col(vectorname[i]);
Then manipulate col as needed. You could even do move construction if you don't need that data in the 2D vector anymore.
I think you have actual logic problems elsewhere though. Show us your vector declarations.
EDIT: What...? You're not declaring vectors at all. You're using pure arrays. And a 2D array shouldn't be called a vector. You're confusing other programmers with your name scheme.
The proper way to declare a vector of strings is
std::vector<string> vectorname(100);
And a vector of vector of strings (a 2D vector) is
std::vector<std::vector<string>(5)> vectorname(101);
But moreover, your dimensions mismatch. Your 1D vectors need to be the same length as the given dimension of your 2D, or 5 (101?) in this case.
If you're trying to copy the values along the first dimension of values, there's no direct constructor for that. You have to manually loop from 0 to 100 and say
arrayname[i] = vectorname[i][n];
Where n is your column number.

Related

Best method for swapping rows in 2d array?

I want to do this in C++ code:
Initialize an array with 4 rows and 5 columns;
Ask the user about two row numbers in the range 0 to 4;
Swap the rows defined by the user in a 2D array.
You can use the following algorithm:
let arr be array
let a,b be row indices that are swapped
for each column index i
swap arr[a][i] and arr[b][i]
However, if instead of a 2d array you were to use an array of row pointers, you could instead simply swap the pointers.
You could declare an extra variable to temporarily hold each value as you swap it from row A to B.
Not sure what you mean by "best", is this in terms of speed or memory requirements?

Does an array of vectors form a 2D vector?

Does the following statements form a 2D vector?
Also mention the dimensions of the vector if it does. Is there another way of declaring a global 2D vector?
Statements:
vector<int> *adj;
adj = new vector<int>[number_of_nodes];
The above statements have been used for declaration of a global adjacency matrix for a graph.
It seems the question isn't clear to much of you. I want to declare a global adjacency list using vectors such that I can use direct addition of edges in graph like v[a].push_back(b). For that, I have to specify first dimension of vector while declaring which I don't have until the main is executed.
No, but it gives similar behaviour. So what you have created is a pointer to an array of vectors. So you will end up with this:
adj[0] = []
adj[1] = []
...
adj[number_nodes] = []
and doing a push_back is a legitimate way to add to the vectors:
adj[0].push_back(some_num) --> adj[0] = [some_num]
But this is a terrible way to approach this! Why?
You are using raw memory that you will have to manage and make sure you delete.
You cant use any of the awesome std::vector functionality on the first dimension of the matrix.
There is no good way to figure out the size of the vector unless you know about the variable number_of_nodes.
... A long list, but you get it.
You can already see that a std::vector can be used as a 1D matrix. So use 2 vectors:
std::vector<std::vector<int>> Matrix2D;
If you need an initial size in some dimension then you can do this:
std::vector<std::vector<int>> Matrix2D(number_of_nodes, std::vector<int>());
Or this:
Matrix2D.resize(number_of_nodes);
Or if that size is fixed at compile time then you could even do this:
const int number_of_nodes = 10;
std::array<std::vector<int>, number_of_nodes> Matrix2D;
Or go extra big and get a library for Matrix use like Eigen.

Cannot access element of 2d heap vector using operator[]

I have a 2d vector that needs to be allocated on the heap and am using the below line of code to declare and size it.
vector<vector<double>> *myArray = new vector<vector<double>>(x, vector<double>(y));
where x and y are the number of rows and columns respectively.
When I try to access an element of the vector using myArray[0][0] = 3.0;, I get the following error,
error: no viable overloaded '='
myArray[0][0] = 3.0;
I would appreciate any help in figuring this out.
Notes:
The number of rows and columns needs to be dynamic, hence myArray is on the heap.
The array needs to be resizable, which is why I am using std::vector.
I understand that I can create a vector of vectors (number of rows) and then in a for-loop resize each row element to the required number of columns. What I do not understand is why the above code does not work since as far as I know it should perform the same function.
For some strange invalid reason, you are using a pointer to a vector. Since operator[] works with pointers, when you do
myArray[0][0] = 3.0;
you are actually accessing a vector<double>, not a double, because myArray[0] gets you a vector<vector<double>>.
The obvious fix is not to use a pointer in the first place:
vector<vector<double>> myArray(x, vector<double>(y));
must be:
(*dataArray)[0][0] = 3.0

How to create variable name with integer appended to the end?

I want to create a for loop that will fill a bunch of arrays with data in c++. Now to save space and in the future once more arrays are added which they will, I have the for loop. Each array for demonstration purposes is called Array# (# being a number) The point of the for loop would be to set a constant with maximum arrays, then cycle through each array filling by appending i to the end of the Array name.
For example in pseudo code:
for (i = 1; i < numberofarrays; i++)
{ fill (Array & i) with ("Array" & i & "-default.txt")}
It is impossible to generate Variable Names by any type of code.
(Meaning it is impossible to generate dynamic variable names on Runtime or on Compiletime)
The best solution possible would be a array of arrays:
int Arrays[][];
Calling Arrays[0] would give you the first array.
If you want to determine the number of arrays during Runtime you need to use pointers!
That would look like that:
(int[])* Arrays = new (int[])[numberofarrays];
Accessing the arrays in the array would work the same!
An alternative would be using the container vector from std.
The code would the look like this:
#include<vector>
// More includes
// Optional
using namespace std;
// Somewhere in your code
vector<vector<int>> Arrays;
You still would acces the elements by using your standard array method (Arrays[15][78] e.g.)
You don't really need the name. You can use an std::vector of arrays. This will not work out of the box, see Correct way to work with vector of arrays
Another approach would be to have an std::map of arrays. You could have the name as the key, if that is what you really want. You will still have to use the same workaround as before to have an array as a value. See Character Array as a value in C++ map for example.

How to Implement a multidimensional array if the dimension is unknown at compile-time?

I want to implement a function that gets as a parameter a dimension "n" of an array of integers. This function also gets values "k_1, k_2, ..., k_n" defining the size of the array. Then this function will fill this n-dimensional array.
How do I implement this efficiently with C++?
For example for n = 3 I would use
vector < vector < vector < int > > > array;
But I don't know the dimension at compile time.
Use a one-dimensional array, and fake the other dimensions using multiplication of offsets for indexing, and you can pass the dimension sizes in by vector, i.e.
std::vector<int> create_md_array(const std::vector<int> & dimensions)
{
int size = std::accumulate(dimensions.begin(), dimensions.end(), 1, std::multiplies<int>());
return std::vector<int>(size);
}
You have a couple of choices. You can implement it yourself, basically multiplying the coordinates by the sizes to linearize the multi-dimensional address, and just have a simple std::vector<whatever> to hold the data.
Alternatively, you could use std::valarray and friends to accomplish the same. It has a set of classes that are specifically intended for the kind of situation you describe -- but they're used so rarely that almost nobody understands them. Writing the code yourself stands a good chance of being easier for most people to read and understand.