-
string check
Hi all,
I need to make a check to see if any strings appear more than once in a array.
Code:
string prev;
for(int i = 0; i < csv_store.size(); i++)
{
prev = csv_store[i].getParent();
// check to see if the string "prev" //appears more than once
}
help please thank you.
-
Just a guess :)
Code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
template<typename T>
class countStr : public unary_function<T,bool>
{
const string &str_;
public:
countStr(const string& str) : str_(str) {}
result_type operator()(const argument_type& t) const {
return (this->str_ == t.getParent());
}
};
struct cvs
{
string str_;
string getParent() const { return this->str_; }
};
int main()
{
vector<cvs> cvs_store;
string toCheck = "prev";
/* fill vector */
cout << "Counted prev: " << count_if(cvs_store.begin(),cvs_store.end(),countStr<cvs>(toCheck)) << endl;
}
-
string check
sorry about that i meant,
Code:
string prev;
for(int i = 0; i < csv_store.size(); i++)
{
prev = csv_store[i].getParent();
// check to see if the strings that are in string prev appears more than once
}
please help
thanks again
-
do you mean something like "find the number of times the word wood appears in the following sentence:"
How much wood could a woodchuck chuck if a woodchuck could cuck wood?
If so does wood need to be a separate word or can it be embedded in another word like woodchuck?
Is that sort of a problem you are trying to solve?
Also, what tools are you allowed to use--native C style string handling only, basic arrays only, the STL algorhithms, or what?
-
ok
in
Code:
csv_store[i].getParent()
holds all of the parent strings, some of those parent strings are duplicated
I need to find out how if and how many time those strings are duplicated and print out one instance of that string.
So in my code I loop through the vector and search for the multiple instances of the strings then record how many times it occurs and print the string that occurs many times, only once.
So if I have a string containing "talk" in
Code:
csv_store[i].getParent()
and it occurs 10 times my output shoulc be
string occurs
_____ ______
talk 10
I hope this helps
Thanks
-
Is there a particular order you want to print the strings in? For example, would it be OK if they printed in alphabetical order?
You already have a vector of strings? If so, that is very easy.
-
yeah thanks, I already have a vector of strings, there is no preference in what order they printed out (first in first out).
Thanks
-
Then sort the vector (if it's OK to be alphabetical) and use equal_range to get a count of each string. Since the end reference returned by equal_range is your typical one-past-the-end reference, you can use that as the starting place for the next search.
Here's some example code:
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
int main()
{
typedef std::vector<std::string> strVec;
typedef strVec::iterator svIter;
typedef std::pair<svIter,svIter> sviPair;
strVec v;
v.push_back("hello");
v.push_back("world");
v.push_back("hello");
v.push_back("abc");
v.push_back("hello");
v.push_back("world");
v.push_back("hello");
v.push_back("world");
v.push_back("abc");
std::sort(v.begin(),v.end());
sviPair p;
for (svIter current = v.begin(); current != v.end(); current = p.second){
p = equal_range(v.begin(),v.end(),*current);
std::cout << *p.first << " " << static_cast<int>(distance(p.first,p.second)) << std::endl;
}
}
Output:
Code:
abc 2
hello 4
world 3
If the array elements are a homemade class (in the example below, I call it MyClass) with a std::string in it (str), just define operator< for the class like so:
Code:
bool MyClass::operator<(const MyClass & obj2)const{
return (str < obj2.str);
}
-
Here's an example of a vector of objects:
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
class MyClass{
private:
std::string str;
int otherData;
/*...*/
public:
MyClass (std::string s = "") : str(s){}
std::string getString()const{return str;}
bool operator< (const MyClass & obj2)const{return str<obj2.str;}
};
int main()
{
typedef std::vector<MyClass> myVec;
typedef myVec::iterator mvIter;
typedef std::pair<mvIter,mvIter> mviPair;
myVec v;
v.push_back(MyClass("hello"));
v.push_back(MyClass("world"));
v.push_back(MyClass("hello"));
v.push_back(MyClass("abc"));
v.push_back(MyClass("hello"));
v.push_back(MyClass("world"));
v.push_back(MyClass("hello"));
v.push_back(MyClass("world"));
v.push_back(MyClass("abc"));
std::sort(v.begin(),v.end());
mviPair p;
for (mvIter current = v.begin(); current != v.end(); current = p.second){
p = equal_range(v.begin(),v.end(),*current);
std::cout << (*p.first).getString() << " "
<< static_cast<int>(distance(p.first,p.second)) << std::endl;
}
}
Output is the same as the other example.
-
If you know the size of the vector, then its a good idea to call the vector::reserve ( size ) function, to reserve the right amount of space (not accessible yet, but prevents unecessary reallocation).
i.e. say v.reserve(9); before the series of push_backs in the above code example.