How do you use a vector in c++? - c++

I am a beginner in c++ and I am trying to understand vectors.
I know the basic format which is:
vector <dataType> vectorName;
People are telling me that vectors are like arrays. But, what I don't
understand is that for arrays you can do this:
array[] = {1, 2, 3}
But for vectors you don't seem to get to set it to a list. Or do you have
to keep using .push_back().
Also, can you use something like vectorName[1] or not?
Can anyone explain this to me?
Thanks.

You can use the style if you use C++11 or later.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec = {1, 2, 3};
std::cout << vec[1] << std::endl;
return 0;
}

The whole purpose of vectors is to be "infinite", so you don't have to redefine it everytime you need to expand it.
push_back is made so you can add/expand to the array without redefining it; you still access and modify like a normal array:
std::vector<int> a;
a.push_back(2);
a.push_back(6);
std::cout << a[0] << std::end; //2
std::cout << a[1] << std::end; //6
a[0] = 5;
a[1] = 7;
std::cout << a[0] << std::end; //5
std::cout << a[1] << std::end; //7
You can also initialize it old-school style (the = is optional):
std::vector<int> a {2, 6};
std::cout << a[0] << std::end; //2
std::cout << a[1] << std::end; //6

Try this for C++:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec { 34,23 };
return 0;
}
Or even:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> v(2);
v = { 34,23 };
return 0;
}

seems non of the above gave you any hint on dealing with the vector after you created it, so, let's say you created it with few initial values.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec { 34,23 };
// use push_back(some_value) if you have multiple values to put inside, say 1000.
// instead of using the index [] brackets, try .at() method
std::cout << vec.at(1) << std::endl;
// use both the .size() or the new syntax to loop over it
for (unsigned i = 0 ; i < vec.size() ; i++){
std::cout << vec.at(i) << std::endl;
}
// or the new syntax
for (auto & i : vec){
std::cout << i << std::endl;
}
return 0;
}
Have fun :)

Vectors are expandable arrays. Unlike an array, you are not restricted to the size you initialized it with.
Growth of vector: the vector doubles it size whenever you overflow it. Underneath the hood its still an array but the "expandable" property of it comes by copying the contents of the previous array into a new larger array.
Few things that you can do with vectors in C++
Initialization of vector
vector<Type> one (size, defaultValue);
vector<Type> two (one); // makes a new vector *two* with the contents of *one*
vector<int> three {1,2,3}; // using initializer list
Accessing an element
int temp = three[2]; //array like syntax
int temp = three.at(2);
You cannot increase the size of a vector using this syntax i.e. you cannot dothree[3]=4;
Expanding
three.pusk_back(4);
Shrinking
three.pop_back();

Related

How to initialize 2D array to false using ranged-based for loop

I am currently stuck trying to use a range base for loop to initialize my array.
What i have currently does it but its not utilizing C++ 11 Array in the constructor. The constructor is void and takes no parameters
//sets everything to flase
for (size_t rowCount = 0; rowCount < NROWS; ++rowCount) {
for (size_t colCount = 0; colCount < NCOLS; ++colCount){
m_Floor[rowCount][colCount] = STARTING_PEN_POSITION;
}
}
Here is what I have so far to set everything to false (starting pen position)
for (auto const &row : m_Floor) {
for (auto const &column : row) {
//something = STARTING_PEN_POSITION;
}
}
and this array is inside the header file
std::array <std::array <bool, NCOLS>, NROWS> m_Floor;
where NCOLS is a constant static of size_t with a value of 70
and NROWS is a constant static of size_t with a value of 22
I am not very clear on the meaning of your question so I will post the answers to the two possible questions I can see above. The first being why your intialization in a range based for loop is not working. As pointed out in the comments, you need to remove the const. Reference the following compilable program for that
#include <iostream>
#include <array>
using std::array;
using std::cout;
using std::endl;
int main() {
array<array<int, 10>, 10> two_dimensional_array;
for (auto& arr : two_dimensional_array) {
for (auto& ele : arr) {
ele = 0;
}
}
// print all the values
for (auto arr : two_dimensional_array) {
for (auto ele : arr) {
cout << ele << " ";
}
cout << endl;
}
return 0;
}
The other question I inferred is that you want a nice way to initialize your 2 dimensional array in one line in the constructor. You can achieve this with vectors. They are dynamic arrays which are usually super optimized. You can use the vector constructor to initialize objects. Reference the following code
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
int main() {
vector<vector<int>> two_dimensional_vector (10, vector<int> (10, 5));
for (auto& vec : two_dimensional_vector) {
for (auto ele : vec) {
cout << ele << " ";
}
cout << endl;
}
return 0;
}
Note that I have not used the uniform initialization syntax because this is one of the places where it can be confusing

Getting Value from particular index in 2d vector in c++

I have made a 2d vector using :
std::vector<std::vector<int> *> hp;
I want to initialise hp vector and get the data from particular index for the same.
for eg,
Getting the values from hp[2][2];
Please do help
Try the following
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<int> *> hp =
{
new std::vector<int> { 1, 2, 3 },
new std::vector<int> { 4, 5, 6 }
};
for ( std::vector<std::vector<int> *>::size_type i = 0;
i < hp.size(); i++ )
{
for ( std::vector<int>::size_type j = 0; j < hp[i]->size(); j++ )
{
std::cout << ( *hp[i] )[j] << ' ';
// std::cout << hp[i]->operator[]( j ) << ' ';
}
std::cout << std::endl;
}
for ( auto &v : hp ) delete v;
return 0;
}
For commented and uncommented statements within the inner loop the program output will be the same and look like
1 2 3
4 5 6
Note that
std::vector<std::vector<int>*> hp
defines a std::vector containing pointers to objects of type
std::vector<int>
As ravi mentioned, you probably want
std::vector<std::vector<int>> hp;
But if you insist on having a vector with pointers,
std::vector<std::vector<int>*> hp;
(*hp[2])[2] // retrieves third value from third std::vector<int>
Remark: In C++11 (also called C++0x) you don't need the spacing between the ">" (as I wrote in the examples).
If these are pointers to vectors that are owned elsewhere:
#include <vector>
#include <iostream>
#include <algorithm>
int main() {
// Create owning vector
std::vector<std::vector<int>> h = {{0,1,2},{3,4,5},{6,7,8}};
// Create vector of pointers
std::vector<std::vector<int>*> hp(h.size());
//auto get_pointer = [](std::vector<int>& v){return &v;}; // C++11
auto get_pointer = [](auto& v){return &v;}; // C++14
std::transform(h.begin(), h.end(), hp.begin(), get_pointer);
// Output value in third column of third row
std::cout << (*hp[2])[2];
}

copying a static array to dynamic array

I am defining a dynamic array in c++:
double *values;
int size = 5;
values = new (nothrow) double[size];
I know this works because it compiles, but I see some potential problems.
Say I want to assign values to this array:
double samples = [1,2,3,4,5,6];
values = samples; //runtime error: free or corruption
What exactly is happening to generate this error?
You should use std::copy to copy a static array to a dynamic array like the example below:
#include <iostream>
#include <algorithm>
int main() {
int *a = new int[5];
int b[] = {1, 2, 3, 4, 5};
std::copy(b, b + 5, a);
for(std::size_t i(0); i < 5; ++i) std::cout << a[i] << " ";
std::cout << std::endl;
return 0;
}
LIVE DEMO
Alternatively if you want the convenience of assignments instead of element-wise copying and provided that you know the size of the arrays in compile time and your compiler supports C++11 features, use std::arrays like the example below:
#include <iostream>
#include <array>
int main() {
std::array<int, 5> a;
std::array<int, 5> b {{1, 2, 3, 4, 5}};
a = b;
for(auto i : a) std::cout << i << " ";
std::cout << std::endl;
return 0;
}
LIVE DEMO
However, it is recommend to prefer std::vector over the use of raw dynamic arrays like the example below:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> a(5);
int b[] = {1, 2, 3, 4, 5};
std::copy(b, b + 5, a.begin());
for(auto i : a) std::cout << i << " ";
std::cout << std::endl;
return 0;
}
LIVE DEMO
It doesn't work because you're assigning a static array to a pointer.
double *values;
double samples[] = {1,2,3,4,5,6};
They're two different data types as far as the compiler is concerned.
When you say:
values = new double[size];
You're creating a block of heap (dynamic) memory, and "values" holds the memory address of the first element in the array. To fill in the values from your static array, you need to assign each element individually like so:
values[0] = samples[0];
values[1] = samples[1];
// or better yet
for (int i = 0; i < size; i++)
values[i] = samples[i]
You can use a std::vector which has an iterator constructor, this will solve the problem for you.
std::vector<double> values(std::begin(samples), std::end(samples));
This will ensure the heap memory is properly cleaned up, even in the case of exception, and employs the implementation's debugging machinery to help protect you from events like buffer overflow.

How to iterate through a list of numbers in c++

How do I iterate through a list of numbers, and how many different ways are there to do it?
What I thought would work:
#include <cstdlib>
#include <iostream>
#include <list>
using namespace std;
int main()
{
int numbers[] = {2, 4, 6, 8};
int i = 0;
for(i=0; i< numbers.size();i++)
cout << "the current number is " << numbers[i];
system("pause");
return 0;
}
I get an error on the for loop line:
request for member 'size' in 'numbers', which is of non-class type 'int[4]'
Unlike a lot of modern languages plain C++ arrays don't have a .size() function. You have a number of options to iterate through a list depending on the storage type.
Some common options for storage include:
// used for fixed size storage. Requires #include <array>
std::array<type, size> collection;
// used for dynamic sized storage. Requires #include <vector>
std::vector<type> collection;
// Dynamic storage. In general: slower iteration, faster insert
// Requires #include <list>
std::list<type> collection;
// Old style C arrays
int myarray[size];
Your options for iteration will depend on the type you're using. If you're using a plain old C array you can either store the size somewhere else or calculate the size of the array based on the size of it's types. Calculating the size of an array has a number of drawbacks outlined in this answer by DevSolar
// Store the value as a constant
int oldschool[10];
for(int i = 0; i < 10; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
// Calculate the size of the array
int size = sizeof(oldschool)/sizeof(int);
for(int i = 0; i < size; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
If you're using any type that provides a .begin() and .end() function you can use those to get an iterator which is considered good style in C++ compared to index based iteration:
// Could also be an array, list, or anything with begin()/end()
std::vector<int> newschool;
// Regular iterator, non-C++11
for(std::vector<int>::iterator num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // * gets the number out of the iterator
*num = 5; // Sets the number.
}
// Better syntax, use auto! automatically gets the right iterator type (C++11)
for(auto num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // As above
*num = 5;
}
// std::for_each also available
std::for_each(newschool.begin(), newschool.end(), function_taking_int);
// std::for_each with lambdas (C++11)
std::for_each(newschool.begin(), newschool.end(), [](int i) {
// Just use i, can't modify though.
});
Vectors are also special because they are designed to be drop-in replacements for arrays. You can iterate over a vector exactly how you would over an array with a .size() function. However this is considered bad practice in C++ and you should prefer to use iterators where possible:
std::vector<int> badpractice;
for(int i = 0; i < badpractice.size(); ++i) {
badpractice[i]; // Get
badpractice[i] = 5; // Set
}
C++11 (the new standard) also brings the new and fancy range based for that should work on any type that provides a .begin() and .end(). However: Compiler support can vary for this feature. You can also use begin(type) and end(type) as an alternative.
std::array<int, 10> fancy;
for(int i : fancy) {
// Just use i, can't modify though.
}
// begin/end requires #include <iterator> also included in most container headers.
for(auto num = std::begin(fancy); num != std::end(fancy); ++num) {
int current = *num; // Get
*num = 131; // Set
}
std::begin also has another interesting property: it works on raw arrays. This means you can use the same iteration semantics between arrays and non-arrays (you should still prefer standard types over raw arrays):
int raw[10];
for(auto num = std::begin(raw); num != std::end(raw); ++num) {
int current = *num; // Get
*num = 131; // Set
}
You also need to be careful if you want to delete items from a collection while in a loop because calling container.erase() makes all existing iterators invalid:
std::vector<int> numbers;
for(auto num = numbers.begin(); num != numbers.end(); /* Intentionally empty */) {
...
if(someDeleteCondition) {
num = numbers.erase(num);
} else {
// No deletition, no problem
++num;
}
}
This list is far from comprehensive but as you can see there's a lot of ways of iterating over a collection. In general prefer iterators unless you have a good reason to do otherwise.
Change you for loop to
for(i=0; i< sizeof(numbers)/sizeof(int);i++){
In simple words,
sizeof(numbers) mean number of elements in your array * size of primitive type int, so you divide by sizeof(int) to get the number of elements
If you fix it so that it's list<int> numbers = {1,2,3,4}:
Iterating through using iterators:
#include <iterator>
for(auto it = std::begin(numbers); it != std::end(numbers); ++it) { ... }
Iterating through using std::for_each:
#include <algorithm>
#include <iterator>
std::for_each(numbers.begin(), numbers.end(), some_func);
Utilizing a for-each loop (C++11):
for(int i : numbers) { ... }
I didn't see it among the answers but this is imo the best way to do it: Range-based for loop
It is safe, and in fact, preferable in generic code, to use deduction to forwarding reference:
for (auto&& var : sequence).
Minimalist and working example :
#include <list>
#include <iostream>
int main()
{
std::list<int> numbers = {2, 4, 6, 8};
for (const int & num : numbers)
std::cout << num << " ";
std::cout << '\n';
return 0;
}
If your list of numbers is fixed be aware that you can simply write:
#include <iostream>
#include <initializer_list>
int main()
{
for (int i : {2, 4, 6, 8})
std::cout << i << std::endl;
return 0;
}
There is no size function on "plain" C-style arrays. You need to use std::vector if you want to use size, or calculate size through sizeof.
In C++11 you can use array initialization syntax to initialize your vectors, like this:
vector<int> numbers = {2, 4, 6, 8};
Everything else stays the same (see demo here).
You can also use the plain old C containers and use the iterator syntax for the loop:
#include <iostream>
int main()
{
int numbers[] = {2, 4, 6, 8};
int *numbers_end = numbers + sizeof(numbers)/sizeof(numbers[0]);
for (int *it = numbers; it != numbers_end; ++it)
std::cout << "the current number is " << *it << std::endl;
return 0;
}
There is no member function "size" because "numbers" isn't a class. You can not get the array's size this way, you must either know it (or compute it) or use some class to store your numbers.
The easiest way to do it, in my opinion, would be to use a span.
#include <cstdlib>
#include <iostream>
#include <gsl/span>
int main() {
int numbers[] = {2, 4, 6, 8};
for(auto& num : gsl::span(numbers)) {
cout << "the current number is " << num;
}
system("pause");
}
Notes:
Spans are part of the GSL library. To use them, download the library from here, and add the download path to the compilation command, e.g. g++ -o foo foo.cpp -I/path/to/gsl
In C++20, span will be part of the standard, so you would just use std::span and #include <span>.

C++ Program Apparently Printing Memory Address instead of Array

#include <iostream>
using namespace std;
int main(){
int findMax(int *);
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
int mval = findMax(values);
cout << values << endl << mval;
return 0;
}
//Function to find the maximum value in the array
int findMax(int arr[]){
int localmax = 0;
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
if(arr[i] > localmax){
localmax = arr[i];
}
}
return localmax;
}
The purpose of this program is for the user to input a space-separated series of values ended by a 0. That array is then to be analyzed to find the max. I figured out how to convert what is originally a char[] into an int[] so that I can use the findMax() function on it without error but the sorting loop seems to have a problem of its own and when "cout << values << endl << mval;" is called, it returns only a memory address instead of what should be a non-spaced sequence of ints. Can anybody explain what I am doing wrong? It seems that I may have made some mistake using the pointers but I cannot figure out what.
Printing values won't print the contents of the array as you expect, it will print the memory location of the first element of the array.
Try something like this instead:
#include <iterator>
#include <algorithm>
// ...
copy(&values[0], &values[MAX], ostream_iterator(cout, " "));
Sorry I can't post actual working code, but your original post is a mess with many syntax and syntactic errors.
EDIT: In the interest of being more complete and more approachable & understandable to beginners, I've written a small program that illustrates 4 ways to accomplish this.
Method 1 uses copy with an ostream_iterator as I've done above.
Method 2 below is probably the most basic & easiest to understand.
Method 3 is a C++0x method. I know the question is tagged C++, but I thought it might be educational to add this.
Method 4 is a C++ approach using a vector and for_each. I've implemented a functor that does the dumping.
Share & Enjoy
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
struct dump_val : public unary_function<int,void>
{
void operator()(int val)
{
cout << val << " ";
}
};
int main(){
int vals[5] = {1,2,3,4,5};
// version 1, using std::copy and ostream_iterator
copy(&vals[0], &vals[5], ostream_iterator<int>(cout, " "));
cout << endl;
// version 2, using a simple hand-written loop
for( size_t i = 0; i < 5; ++i )
cout << vals[i] << " ";
cout << endl;
// version 3, using C++0x lambdas
for_each(&vals[0], &vals[5], [](int val)
{
cout << val << " ";
}
);
cout << endl;
// version 4, with elements in a vector and calling a functor from for_each
vector<int> vals_vec;
vals_vec.push_back(1);
vals_vec.push_back(2);
vals_vec.push_back(3);
vals_vec.push_back(4);
vals_vec.push_back(5);
for_each( vals_vec.begin(), vals_vec.end(), dump_val() );
cout << endl;
}
When you pass around an array of X it's really a pointer to an array of X that you're passing around. So when you pass values to cout it only has the pointer to print out.
You really should look into using some of the standard algorithms to make your life simpler.
For example to print all the elements in an array you can just write
std::copy(values, values+MAX, std::ostream_iterator<int>(std::cout, "\n"));
To find the max element you could just write
int mval = *std::max_element(values, values+MAX);
So your code becomes
#include <iostream>
using namespace std;
int main(){
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
copy(values, values+MAX, ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values, values+MAX);
return 0;
}
Doing this removes the need for your findMax method altogether.
I'd also re-write your code so that you use a vector instead of an array. This makes your code even shorter. And you can use stringstream to convert strings to numbers.
Something like this should work and is a lot less code than the original.
int main(){
vector<int> values;
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
int temp = 0;
stringstream ss(ivals);
//read the next int out of the stream and put it in temp
while(ss >> temp) {
//add temp to the vector of ints
values.push_back(temp);
}
copy(values.begin(), values.end(), ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values.begin(), values.end());
return 0;
}
Array of int is promoted to a pointer to int when passed to a function. There is no operator << taking ordinary array. If you want to use operator << this way, you need to use std::vector instead.
Note: it is possible technically to distinguish array when passed to a function using template, but this is not implemented for standard operator <<.
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
sizeof(arr) here is the size of the pointer to the array. C++ will not pass the actual array, that would be grossly inefficient. You'd typically only get one pass through the loop. Declare your function like this:
int findMax(int* arr, size_t elements) {
//...
}
But, really, use a vector.
Oh, hang on, the question. Loop through the array and print each individual element.