vector<string>::iterator - how to find position of an element - c++

I am using the following code to find a string in an std::vector of string type. But how to return the position of particular element?
Code:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<string> vec;
vector<string>::iterator it;
vec.push_back("H");
vec.push_back("i");
vec.push_back("g");
vec.push_back("h");
vec.push_back("l");
vec.push_back("a");
vec.push_back("n");
vec.push_back("d");
vec.push_back("e");
vec.push_back("r");
it=find(vec.begin(),vec.end(),"r");
//it++;
if(it!=vec.end()){
cout<<"FOUND AT : "<<*it<<endl;
}
else{
cout<<"NOT FOUND"<<endl;
}
return 0;
}
Output:
FOUND AT : r
Expected Output:
FOUND AT : 9

You can use std::distance for that:
auto pos = std::distance(vec.begin(), it);
For an std::vector::iterator, you can also use arithmetic:
auto pos = it - vec.begin();

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<string> vec;
vector<string>::iterator it;
vec.push_back("H");
vec.push_back("i");
vec.push_back("g");
vec.push_back("h");
vec.push_back("l");
vec.push_back("a");
vec.push_back("n");
vec.push_back("d");
vec.push_back("e");
vec.push_back("r");
it=find(vec.begin(),vec.end(),"a");
//it++;
int pos = distance(vec.begin(), it);
if(it!=vec.end()){
cout<<"FOUND "<< *it<<" at position: "<<pos<<endl;
}
else{
cout<<"NOT FOUND"<<endl;
}
return 0;

Use following :
if(it != vec.end())
std::cout<< "Found At :" << (it-vec.begin()) ;

Use this statement:
it = find(vec.begin(), vec.end(), "r") - vec.begin();

Related

no match for ‘operator==’

I am having trouble figuring out what error there is in my code. It is supposed to take the input map and find the certain string in the key. If it finds that string in the key of a pair, it is supposed to add values associated with the key to a vector and find the final sum. I keep getting this error, though.
no match for ‘operator==’ (operand types are ‘const char’ and ‘const std::__cxx11::basic_string<char>’)
And I am unsure where in my code this error would arise. Here is my code below:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <map>
using std::cout;
using std::endl;
using std::cin;
using std::string;
using std::vector;
using std::map;
int GetPointTotalForStudent(map<string, string> &input, string type_of){
vector<int> temp;
std::transform(input.begin(), input.end(), input.begin(), [type_of, temp](auto a) mutable{
if(std::find(a.first.begin(), a.first.end(), type_of) != a.first.end()){
temp.push_back(std::stoi(a.second));
}
});
int total = std::accumulate(temp.begin(), temp.end(), 0);
return total;
}
int main(){
map<string, string> TP_Map;
string type_of = "Exam";
TP_Map.insert({"Exam 1", "80"});
TP_Map.insert({"Project", "75"});
TP_Map.insert({"Exam 2", "90"});
GetPointTotalForStudent(TP_Map, type_of);
}
If you have access to c++ 17 you can do something like the following, which preserves your original vision.
return std::transform_reduce(
input.begin(), input.end(), 0, std::plus(), [type_of](auto a) {
if (a.first.find(type_of) != std::string::npos) {
return std::stoi(a.second);
}
return 0;
});
However, I think you might have overcomplicated the design by using std::transform, I personally would probably favor something simpler like:
int total = 0;
for(const auto& kvp : input){
if(kvp.first.find(type_of) != std::string::npos){
total += std::stoi(kvp.second);
}
}
return total;
using std::for_each
int total = 0;
std::for_each(input.begin(), input.end(), [type_of, &total](auto kvp) {
if (kvp.first.find(type_of) != std::string::npos) {
total += std::stoi(kvp.second);
}
});
return total;

count number of occurrences of a string in a vector of string

My requirement is to count the number of occurences of a string inside a vector of string. The string to be searched is at 0th index of the vector.
I am using the inbuilt count function from algorithm header, but getting a weird compilation error, which I am not able to resolve.
My Code:
vector<string> a={"abc", "def", "abc"};
int cnt = count(a.begin(), a.end(), a[0]);
Compilation error message is:
count(std::vector<std::basic_string<char> >)':
error: no matching function for call to std::vector<std::basic_string<char> >::iterator, std::vector<std::basic_string<char> >::iterator, __gnu_cxx::__alloc_traits<std::allocator<std::basic_string<char> > >::value_type&)'
int cnt = count(a.begin(), a.end(), a[0]);
Any help? What is the issue here?
You mentioned algorithm library but be sure you have added #include <algorithm>.
With your algorithm it works well here on code
#include <iostream> // std::cout
#include <algorithm> // std::count
#include <vector> // std::vector
#include <string> // std::vector
using namespace std;
int main () {
// counting elements in container:
vector<string> a {"abc", "def", "abc"};
int cnt = count(a.begin(), a.end(), a.at(0));
std::cout << a.at(0) << " " << cnt << " times.\n";
return 0;
}
Compiler flag:
-------------- Build: Debug in test (compiler: GNU GCC Compiler)---------------
mingw32-g++.exe -Wall -fexceptions -g -Weffc++ -std=c++14
Besides, my solution may be useful for you
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<string> stringList;
stringList.push_back("abc");
stringList.push_back("def");
stringList.push_back("111 abc");
string searchWord ("abc");
int searchWordSize = searchWord.size();
int count = 0;
for (vector<string>::iterator iter = stringList.begin(); iter != stringList.end(); ++iter) {
for (size_t pos = 0; pos < (*iter).length(); pos += searchWordSize) {
pos = (*iter).find(searchWord, pos);
if (pos != string::npos) ++count;
else break;
}
}
cout << "Count: " << count << endl;
return 0;
}

removing specific element from vector's range

I want to delete element if its value is matching the string "empty", so iterate thorough loop but its not working that way.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main ()
{
std::vector<std::string> myvector;
myvector.push_back("value");
myvector.push_back("value");
myvector.push_back("empty");
myvector.push_back("value");
myvector.push_back("value");
myvector.push_back("empty");
myvector.push_back("empty");
int index = 0;
for(string input: myvector){
if(input == "empty")
myvector.erase(myvector.begin()+index,myvector.begin()+index);
index++;
}
for(string input: myvector){
cout << input << endl;
}
return 0;
}
but we can see that nothing is deleted?
ouput :
value
value
empty
value
value
empty
empty
Looking for something like below but doesn't exists
myvector.erase(myvector.begin(),myvector.end(),"empty");
so how to achieve it in less complexity?
You should use std::remove_if like this:
myvector.erase(std::remove_if(myvector.begin(), myvector.end(), [](const std::string& string){ return (string == "empty"); }), myvector.end());
std::vector<std::string> myvector;
myvector.push_back("value");
myvector.push_back("value");
myvector.push_back("empty");
myvector.push_back("value");
myvector.push_back("value");
myvector.push_back("empty");
myvector.push_back("empty");
auto it = std::remove_if(myvector.begin(), myvector.end(),
[](const std::string& s)
{
return (s== "empty");
});
myvector.erase(it, myvector.end());
use remove_if to put all found "empty" at the end of vector.
use returned iterator to erase them.

Sorting a string using STL

I am trying to sort the characters of a string using C++ STL and came up with this code.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main()
{
using namespace std;
vector<string>::iterator it;
string arr[] = {"jajajaj"};
vector<string> v(arr, arr+2);
sort(v.begin(), v.end());
for (it=v.begin(); it<v.end(); it++) {
cout << *it;
}
return 0;
}
But unfortunately its not sorting properly when the array contains single element. How to do it using STL.
Please help.
You can sort the string using std::string class.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string str = "jajajaj";
sort(str.begin(), str.end());
cout << str;
return 0;
}
Hope this might be helpful.
If you need a string, use a std::string :
(I used a for-range loop to make the code cleaner)
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string s = {"jajajaj"};
sort(s.begin(), s.end());
for (auto c : s)
cout << c;
return 0;
}
Outputs:
aaajjjj
Note:
Your current code is not working because, as commented, you create a vector of size 2 out of an array of size 1, which has undefined behavior.
You seem to be confusing a std::string with an array of chars.
int main()
{
using namespace std;
string arr = "jajajaj";
vector<char> v(arr.begin(), arr.end());
sort(v.begin(), v.end());
vector<char>::iterator it;
for (it=v.begin(); it<v.end(); ++it) {
cout << *it;
}
return 0;
}
I haven't tested that, but it should work....
UPDATE:
Alternately, we could just sort the string's character directly: (Thanks guys!)
int main()
{
using namespace std;
string arr = "jajajaj";
sort(arr.begin(), arr.end());
cout << arr;
return 0;
}
You can use sort() function. sort() exists in algorithm header file
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string str = "sharlock";
sort(str.begin(), str.end());
cout<<str<<endl;
return 0;
}
Output:
achklors
In order to sort a string, just input string from the user and use the sort() in STL for it.
#include<bits/stdc++.h>
using namespace std;
int main()
{
string arr;
cin >>arr;
sort(arr.begin(), arr.end());
cout <<arr;
}
See the sample image below for the output with input string as "Michael".

Infinite loop on 'getline' in Visual Studio 2010

I am working through some C++ exercises in Visual Studio 2010, and I keep having problems with an infinite loop which occurs when I try to terminate a standard in stream with "CTRL-Z", when using the getline() function. Here is the relevant bit of code....
// find all the lines that refer to each word in the input
map<string, vector<int> >
xref(istream& in,
vector<string> find_words(const string&) = split)
{
string line;
int line_number = 0;
map<string, vector<int> > ret;
// read the next line
while (getline(in, line)) {
++line_number;
// break the input line into words
vector<string> words = find_words(line);
// remember that each word occurs on the current line
for (vector<string>::const_iterator it = words.begin();
it != words.end(); ++it)
ret[*it].push_back(line_number);
}
return ret;
}
...instead of kicking me out of the while loop, the program goes into an infinite loop printing a random integer. I'm pretty sure this is something specific to the Windows environment that I'm missing. Here's the entire code...
#include <algorithm>
#include <cctype>
#include <string>
#include <vector>
#include "split.h"
using std::find_if;
using std::string;
using std::vector;
using std::isspace;
// `true' if the argument is whitespace, `false' otherwise
bool space(char c)
{
return isspace(c);
}
// `false' if the argument is whitespace, `true' otherwise
bool not_space(char c)
{
return !isspace(c);
}
vector<string> split(const string& str)
{
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while (i != str.end()) {
// ignore leading blanks
i = find_if(i, str.end(), not_space);
// find end of next word
iter j = find_if(i, str.end(), space);
// copy the characters in `[i,' `j)'
if (i != str.end())
ret.push_back(string(i, j));
i = j;
}
return ret;
}
#include <map>
#include <iostream>
#include <string>
#include <vector>
#include "split.h"
using std::cin; using std::cout;
using std::endl; using std::getline;
using std::istream; using std::string;
using std::vector; using std::map;
// find all the lines that refer to each word in the input
map<string, vector<int> >
xref(istream& in,
vector<string> find_words(const string&) = split)
{
string line;
int line_number = 0;
map<string, vector<int> > ret;
// read the next line
while (getline(in, line)) {
++line_number;
// break the input line into words
vector<string> words = find_words(line);
// remember that each word occurs on the current line
for (vector<string>::const_iterator it = words.begin();
it != words.end(); ++it)
ret[*it].push_back(line_number);
}
return ret;
}
int main()
{
// call `xref' using `split' by default
map<string, vector<int> > ret = xref(cin);
// write the results
for (map<string, vector<int> >::const_iterator it = ret.begin();
it != ret.end(); ++it) {
// write the word
cout << it->first << " occurs on line(s): ";
// followed by one or more line numbers
vector<int>::const_iterator line_it = it->second.begin();
cout << *line_it; // write the first line number
++line_it;
// write the rest of the line numbers, if any
while (line_it != it->second.end()) {
cout << ", " << *line_it;
++line_it;
}
// write a new line to separate each word from the next
cout << endl;
}
return 0;
}
I think instead of trying to make this work, I'd start by writing code I could understand (and for me to understand it, the code has to be fairly simple):
#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
#include "infix_iterator.h"
typedef std::map<std::string, std::vector<unsigned> > index;
namespace std {
ostream &operator<<(ostream &os, index::value_type const &i) {
os << i.first << ":\t";
std::copy(i.second.begin(), i.second.end(),
infix_ostream_iterator<unsigned>(os, ", "));
return os;
}
}
void add_words(std::string const &line, size_t num, index &i) {
std::istringstream is(line);
std::string temp;
while (is >> temp)
i[temp].push_back(num);
}
int main() {
index i;
std::string line;
size_t line_number = 0;
while (std::getline(std::cin, line))
add_words(line, ++line_number, i);
std::copy(i.begin(), i.end(),
std::ostream_iterator<index::value_type>(std::cout, "\n"));
return 0;
}
As (more or less) usual, this needs the infix_ostream_iterator I've posted elsewhere.