954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

vector<string> - way to find longest string?

If I've got a vector of strings, is there a quick one liner that gets me the longest (ie .size() ) of the string inside (or conversely, the shortest?)

The alternatives I've thought of are as follows, but they all seem inefficient:
- Keep a variable of the longest size as I insert each element and compare
- Iterate through the vector and compare

Any other ideas would be appreciated.

winbatch
Posting Pro in Training
466 posts since Feb 2005
Reputation Points: 68
Solved Threads: 18
 

>The alternatives I've thought of are as follows, but they all seem inefficient
They seem inefficient, or they are inefficient? Chances are good that there's no performance issue and your time is better spent elsewhere.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

As long as there is no built in function that I'm not aware of, I'll iterate through...

winbatch
Posting Pro in Training
466 posts since Feb 2005
Reputation Points: 68
Solved Threads: 18
 

>As long as there is no built in function that I'm not aware of, I'll iterate through...
Don't confuse my comment with there not being another solution. However, you'll find that the pretty abstractions that you might use do exactly the same thing internally, so your concern about performance is pretty much moot.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 
>Don't confuse my comment with there not being another solution.



Ok, bug I'd rather not rewrite something that already exists, so are you aware of an existing solution provided by vector or algorithm in general?

winbatch
Posting Pro in Training
466 posts since Feb 2005
Reputation Points: 68
Solved Threads: 18
 

Why not use a Set and specify the string size as a sorting criterion? That way, when you want to find the longest or shortest string it would be a one liner.

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

This is my try at it. It may not be very good, but it works.

#include <iostream>
#include <algorithm>
#include <string>
#include <set>
using std::cout;
using std::endl;


class Sort_By_Length
{
   public:
      enum sort_mode {ascending, descending};

      //constructor for sorting criterion
      //-default criterion uses value descending
      Sort_By_Length(sort_mode m=descending): mode(m) { }

      //comparison of the elements
      bool operator() (const string& s1, const string& s2) const
      {
         return  (mode == descending ? s1.length() > s2.length() : s2.length() > s2.length());
      }

      //comparison of the sorting criterion
      bool operator== (const Sort_By_Length& sbl)
      {
         return mode == sbl.mode;
      }


   private:
      sort_mode mode;
};



typedef set<string, Sort_By_Length> String_Set;
void fill_set(String_Set& set);

int main()
{
   //create, fill, and print set with normal element order
   //-uses default sorting criterion
   String_Set coll;
   fill_set(coll);

   copy(coll.begin(), coll.end(), //range
        ostream_iterator<string>(cout, "\n")); //destination
   cout << endl;
}

void fill_set(String_Set& set)
{
   set.insert("reallylarge");
   set.insert("small");
   set.insert("medium");
}
server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

>so are you aware of an existing solution provided by vector or algorithm in general?
If you have to use a vector, you can sort by length and then take the last string as your longest:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct length {
  bool operator() ( const string& a, const string& b )
  {
    return a.size() < b.size();
  }
};

int main()
{
  string init[] = {
    "This","is","a","test","and","aaaaa"
  };
  vector<string> v ( init, init + 6 );

  sort ( v.begin(), v.end(), length() );

  cout<< v.back() <<'\n';
}

Alternatively, because you might not need the vector sorted as well and a simple search might be more than enough, you can use max_element with the length predicate:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct length {
  bool operator() ( const string& a, const string& b )
  {
    return a.size() < b.size();
  }
};

int main()
{
  string init[] = {
    "This","is","a","test","and","aaaaa"
  };
  vector<string> v ( init, init + 6 );

  cout<< *max_element ( v.begin(), v.end(), length() ) <<'\n';
}

If you're doing more searching than anything else, a vector might not be an appropriate data structure to begin with.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 
cout<< *max_element ( v.begin(), v.end(), length() ) <<'\n';


That's pretty sweet. I guess mine was blown way out of proportion.

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

Thanks for your attempts Narue and SC. In the end though, it looks like the solutions still iterate through each element and see if it's the largest or not. I guess the only way this would not have been in the case was if vector automatically had already stored the longest and shortest values as they were inserted. (Although I guess that's not likely/practical given that the container might be used to store data of any kind and therefore longest/shortest may not have any meaning in all contexts).

thanks again guys.
Winbatch

This is what I ended up using/writing:
void General::getMinimumAndMaximumLengths( vector & vec, int & min, int & max, string & minStr, string & maxStr )
{
if ( vec.empty() )
{
min=max=0;
minStr.clear();
maxStr.clear();
}
else
{


for (unsigned int i=0;i< vec.size();i++)
{

unsigned int current = vec[i].size();
if ( i==0 )
{
min=max=current;
minStr=maxStr = vec[i];
}

if ( current <=min )
{
min = current;
minStr = vec[i];
}

if ( current >=max )
{
max = current;
maxStr = vec[i];
}
}

}

}

winbatch
Posting Pro in Training
466 posts since Feb 2005
Reputation Points: 68
Solved Threads: 18
 

>In the end though, it looks like the solutions still iterate
>through each element and see if it's the largest or not.
Oddly enough, that's what I told you in the first place. :rolleyes: At the very least, you have a few more ideas now.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

Narue, 'queen of holiday spirit' ;)

winbatch
Posting Pro in Training
466 posts since Feb 2005
Reputation Points: 68
Solved Threads: 18
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You