Index of vector of strings in c++ [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a vector of string including :- chemistry physics maths.
I want to access first character of each word ie c of chemistry p of physics and m of maths. How to do that?

You can output the first index element through this process.
I have made a 2D vector and applied a for loop so each row of the vector's first element is printed.
#include <iostream>
#include <vector>
int main()
{
std::vector<std::string> vec = {"chemistry", "maths", "physics"};
for(int i=0;i<vec.size();i++)
{
std::cout << vec[i][0];
}
return EXIT_SUCCESS;
}
You can also use a range based for loop
for (auto &i : vec)
std::cout << i[0] << " ";
The output will be
c m p

You can treat it like a 2D matrix of characters.
Given the vector of strings:
std::vector<std::string> vec = {"chemestry", "physics", "math"};
You can use a normal loop to access all first characters:
for (int i = 0; i < vec.size(); i++)
std::cout << vec[i][0] << " ";
Or a range based loop:
for (auto &str : vec)
std::cout << str[0] << " ";
Output:
c p m

I think this code should do the trick. If not then the Compiler is being a racist and doesn't like you that much. In that case you can just go-to your old buddy cpp.sh :D
String is a char Array and you can access it's contents from indexes like so
std::string str = "Hello";
std::cout << "First Index: " << str[0];
Output:-
H
Same goes for the vector as well
std::vector <char> str = "World!";
std::cout << "First Index: " << str[0];
Output:-
W
Now if you combine those two, it makes it a 2D Array so you have to access it like you access data from a 2D Array/Matrix.
std::vector <std::string> str = {"Hello", "World", "!"};
std::cout << "First Index Of Element 1: " << str[0][0] << std::endl
<< "First Index Of Element 2: " << str[1][0] << std::endl
<< "First Index Of Element 3: " << str[2][0] << std::endl;
Output:-
H
W
!
Program:-
#include <iostream>
#include <vector>
int main() {
std::vector <std::string> vec = {"chemistry", "physics", "math"};
for (int i=0; i < vec.size(); i++) { //-- size(); Function gives the size of a vector
std::cout << vec[i][0] << std::endl;
}
return 0;
}
Output:-
c
p
m
Press any key to continue...

Related

can I print the index of an element in an object vector?

So I know to print something in a loop, the code looks like this:
for(int I = 0; I < num; ++I)...
And to print an object vector:
for(Square sq : squares)...
(if I have a class Square and I create the object sq and squares is the name of the vector)
But how would I go about code if I want my output to look like:
square 1 area: 3
square 2 area: 6
square 3 area: 9
To be more clear: my question is, how do I incorporate "I" like in the first example in a loop where I'm printing objects?
You can do it like this:
for (size_t idx=0; idx<squares.size(); ++idx)
{
Square const & sq = squares[idx];
// Here you can use both:
// idx (which is the index in the vector),
// and sq (reference to the element).
}
The fact that sq is a std::vector does not mean you must traverse it using the range-based loop (Range-based for loop).
A std::vector has a method for getting its size (std::vector::size), and operator[] to access an element (std::vector::operator[]).
Note - even if you do use the range-based loop, it is better to use a refernce (or const reference) to avoid unnecessary copies:
for(Square const & sq : squares) // without `const` if you need to modify the element
{
//...
}
You can also combine range based for and another index variable
// with c++20 range-based for can have initializer in it
for(auto i=1; auto& s:squares){
std::cout << "square " << i << " area: " << s << '\n' ;
++i;
}
https://godbolt.org/z/EfhefdoGP
pre-c++20
{
auto i=1;
for(auto& s:squares){
std::cout << "square " << i << " area: " << s << '\n' ;
++i;
}
}
Because the elements of the vector are lined up continuously... It may be possible to do something like this.
class Object
{
public:
Object( int a, int b ) : a(a),b(b) {}
int a,b;
};
int main()
{
std::vector<Object> Vec{ {1,2}, {10,20}, {100,200} };
for( const auto &obj : Vec )
{
auto index = &obj - &Vec[0]; //calculate index of element
std::cout << index << " : " << obj.a << "," << obj.b << std::endl;
}
return 0;
}

C++ finding uint8_t in vector<uint8_t>

I have the following simple code. I declare a vector and initialize it with one value 21 in this case. And then i am trying to find that value in the vector using find. I can see that the element "21" in this case is in the vector since i print it in the for loop. However why the iterator of find does not resolve to true?
vector<uint8_t> v = { 21 };
uint8_t valueToSearch = 21;
for (vector<uint8_t>::const_iterator i = v.begin(); i != v.end(); ++i){
cout << unsigned(*i) << ' ' << endl;
}
auto it = find(v.begin(), v.end(), valueToSearch);
if ( it != v.end() )
{
string m = "valueToSearch was found in the vector " + valueToSearch;
cout << m << endl;
}
are you sure it doesn't work?
I just tried it:
#include<iostream> // std::cout
#include<vector>
#include <algorithm>
using namespace std;
int main()
{
vector<uint8_t> v = { 21 };
uint8_t valueToSearch = 21;
for (vector<uint8_t>::const_iterator i = v.begin(); i != v.end(); ++i){
cout << unsigned(*i) << ' ' << endl;
}
auto it = find(v.begin(), v.end(), valueToSearch);
if ( it != v.end() )
{// if we hit this condition, we found the element
string error = "valueToSearch was found in the vector ";
cout << error << int(valueToSearch) << endl;
}
return 0;
}
There are two small modifications:
in the last lines inside the "if", because you cannot add directly a
number to a string:
string m = "valueToSearch was found in the vector " + valueToSearch;
and it prints:
21
valueToSearch was found in the vector 21
while it's true that you cannot add a number to a string, cout
support the insertion operator (<<) for int types, but not uint8_t,
so you need to convert it to it.
cout << error << int(valueToSearch) << endl;
This to say that the find is working correctly, and it is telling you that it found the number in the first position, and for this, it != end (end is not a valid element, but is a valid iterator that marks the end of your container.)
Try it here

vector element compare c++

This program takes a word from text and puts it in a vector; after this it compares every element with the next one.
So I'm trying to compare element of a vector like this:
sort(words.begin(), words.end());
int cc = 1;
int compte = 1;
int i;
//browse the vector
for (i = 0; i <= words.size(); i++) { // comparison
if (words[i] == words[cc]) {
compte = compte + 1;
}
else { // displaying the word with comparison
cout << words[i] << " Repeated : " << compte; printf("\n");
compte = 1; cc = i;
}
}
My problem in the bounds: i+1 may exceed the vector borders. How to I handle this case?
You need to pay more attention on the initial conditions and bounds when you do iteration and comparing at the same time. It is usually a good idea to execute your code using pen and paper at first.
sort(words.begin(), words.end()); // make sure !words.empty()
int cc = 0; // index of the word we need to compare.
int compte = 1; // counting of the number of occurrence.
for( size_t i = 1; i < words.size(); ++i ){
// since you already count the first word, now we are at i=1
if( words[i] == words[cc] ){
compte += 1;
}else{
// words[i] is going to be different from words[cc].
cout << words[cc] << " Repeated : " << compte << '\n';
compte = 1;
cc = i;
}
}
// to output the last word with its repeat
cout << words[cc] << " Repeated : " << compte << '\n';
Just for some additional information.
There are better ways to count the number of word appearances.
For example, one can use unordered_map<string,int>.
Hope this help.
C++ uses zero-based indexing, e.g., an array of length 5 has indices: {0, 1, 2, 3, 4}. This means that index 5 is outside of the range.
Similarly, given an array arr of characters:
char arr[] = {'a', 'b', 'c', 'd', 'e'};
The loop for (int i = 0; i <= std::size(arr); ++i) { arr[i]; } will cause a read from outside of the range when i is equal to the length of arr, which causes undefined behaviour. To avoid this the loop must stop before i is equal to the length of the array.
for (std::size_t i = 0; i < std::size(arr); ++i) { arr[i]; }
Also note the use of std::size_t as type of the index counter. This is common practice in C++.
Now, let's finish with an example of how much easier this can be done using the standard library.
std::sort(std::begin(words), std::end(words));
std::map<std::string, std::size_t> counts;
std::for_each(std::begin(words), std::end(words), [&] (const auto& w) { ++counts[w]; });
Output using:
for (auto&& [word, count] : counts) {
std::cout << word << ": " << count << std::endl;
}
My problem in the bounds: i+1 may exceed the vector borders. How to I
handle this case?
In modern C++ coding, the problem of an index going past vector bounds can be avoided. Use the STL containers and avoid using indices. With a little effort devoted to learning how to use containers this way, you should never see these kind of 'off-by-one' errors again! As a benefit, the code becomes more easily understood and maintained.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main() {
// a test vector of words
vector< string > words { "alpha", "gamma", "beta", "gamma" };
// map unique words to their appearance count
map< string, int > mapwordcount;
// loop over words
for( auto& w : words )
{
// insert word into map
auto ret = mapwordcount.insert( pair<string,int>( w, 1 ) );
if( ! ret.second )
{
// word already present
// so increment count
ret.first->second++;
}
}
// loop over map
for( auto& m : mapwordcount )
{
cout << "word '" << m.first << "' appears " << m.second << " times\n";
}
return 0;
}
Produces
word 'alpha' appears 1 times
word 'beta' appears 1 times
word 'gamma' appears 2 times
https://ideone.com/L9VZt6
If some book or person is teaching you to write code full of
for (i = 0; i < ...
then you should run away quickly and learn modern coding elsewhere.
Same repeated words counting using some C++ STL goodies via multiset and upper_bound:
#include <iostream>
#include <vector>
#include <string>
#include <set>
int main()
{
std::vector<std::string> words{ "one", "two", "three", "two", "one" };
std::multiset<std::string> ms(words.begin(), words.end());
for (auto it = ms.begin(), end = ms.end(); it != end; it = ms.upper_bound(*it))
std::cout << *it << " is repeated: " << ms.count(*it) << " times" << std::endl;
return 0;
}
https://ideone.com/tPYw4a

Range based for loop starts at one instead of zero?

I have just started using range based for loops to simplify my code when using templates. I have come across a strange error and am not sure if this is something that I am missing or if the compiler is making a mistake. I have written a piece of code to illustrate the issue that I am having as well as the output. These are shown below.
Note: I am using the Mingw64 compiler on windows g++ (rev5, Built by MinGW-W64 project) 4.8.1 compiled without optimization with the --std=c++11 flag.
Code:
#include <iostream>
#include <array>
#include <vector>
int main()
{
// Declares an array of size 5 and of type int and intialises.
std::array<int,5> x = {1,2,3,4,5};
std::vector<int> y = {1,2,3,4,5};
// Prints each element
std::cout << "Array:" << std::endl;
std::cout << "x" << "\t" << "i" << std::endl;
for (auto i : x)
{
std::cout << x[i] << "\t" << i << std::endl;
}
std::cout << "Vector" << std::endl;
std::cout << "y" << "\t" << "i" << std::endl;
for (auto i : y)
{
std::cout << y[i] << "\t" << i << std::endl;
}
std::cin.get();
std::cin.get();
return 0;
}
Output:
Array:
x i
2 1
3 2
4 3
5 4
0 5
Vector
y i
2 1
3 2
4 3
5 4
1313429340 5
I would assume that the last line of both the vector and array output is an overflow, and notice how i starts at one instead of zero?? I would have assumed it would behave as described here.
I think you have not understood the syntax correctly
for (auto i : x)
here i is not an index of an array, it is the actual element inside the vector x.
So it is doing its job correctly.
"i" is the actual value in the array and not the index. So it is printing x[1] to x[5] in the first column and 1 to 5 in the second column. To access the values just print "i".
for (auto i : x)
creates copies of elements in x to be used inside your for loop. Use an iterator instead to access elements by their index.
for (size_t i = 0; i < x.size(); i++) {
std::cout << x[i] << "\t" << i << std::endl;
}

Remove an element from vector and change the size [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I try to remove elements from a vector and it works fine with the erase() methode, but after removing the element the size of the vector still the same.
std::vector<int> myvector;
myvector.push_back (1);
myvector.push_back (2);
myvector.push_back (3);//here the size is 3
myvector.erase(myvector.begin()+1);//I think normally the size should be 2 after removing the element
is there a function that can do that or should I do it manually, I'm new to c++ I checked the documentation and I didn't found a solution for this.
The size is changed then an element of a vector is removed with using member function erase. If you mean capacity then it will not be changed.
Here is a demonstrative program
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v { 1, 2, 3 };
std::cout << "v.size() = " << v.size() << std::endl;
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
v.erase( v.begin() + 1 );
std::cout << "v.size() = " << v.size() << std::endl;
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
The output is
v.size() = 3
1 2 3
v.size() = 2
1 3