Reputation: 89
I'm writing an algorithm which takes random strings as input. I need to output the maximum length encountered and also how many words have that particular length. YES, I know I can use a different approach but I was thinking to store each string in a v[it's length] and if there are multiple strings with the same length then I would increment u[same length], then just output those values. How can I check whether v[length] is already set?
Sorry for possible bad English.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef unsigned short us;
typedef vector<string> vstr;
typedef vector<us> vus;
int main()
{
string str;
vstr v;
vus u(50, 1);
us len;
while (cin >> str && str != "0")
{
len = str.length();
//if there is an element set at v[len] then ++u[len] otherwise v[len] = str;
}
//bunch of other code
return 0;
}
Upvotes: 0
Views: 666
Reputation: 126582
YES, I know I can use a different approach
Honestly, I really believe you'd be better off following a different approach then.
You don't need a vector of lengths at all, nor a map, and neither you need a vector of strings unless you want to display those strings as well (here, I will assume you do need it). Finally, you don't even need to know the maximum length of those strings:
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::string> words;
std::string::size_type maxLength = 0;
std::string str;
while (std::cin >> str)
{
auto len = str.length();
if (len == maxLength)
{
words.push_back(str);
}
else if (len > maxLength)
{
maxLength = len;
words.clear();
words.push_back(str);
}
}
std::cout << "Max length: " << maxLength << std::endl;
std::cout << "# of words with max length: " << words.size() << std::endl;
std::cout << "Words with max length: " << std::endl;
for (auto const& s : words) { std::cout << s << std::endl; }
return 0;
}
Upvotes: 3
Reputation: 171501
A std::vector v
has a length given by v.size()
, and all elements in the range [0,v.size())
exist.
So an element exists at v[n]
if v.size() > n
You can test for it either by checking the vector's length, or accessing the element with v.at(n)
instead of v[n]
because the at()
function will throw an exception if the element doesn't exist (that is, if the length is not at least n
)
The fact a std::vector
contains an element at every index up to its length means it is not an efficient representation of a sparse array To represent a sparse array with one of the standard containers it is better to use std::map
because it doesn't require elements to have contiguous keys.
Upvotes: 0
Reputation: 8049
This won't work unless you know the maximum length of any possible string beforehand. Let's call this maximum X. Then you can construct a vector of X ints, initialized to 0, and just increment the one you need using the subscript operator.
std::vector<int> counts(X, 0); // X ints, initialized to 0
for (const string str : v) {
int length = str.size();
try {
counts.at(length)++;
} catch (const std::out_of_range& oor) {
// Your professor lied to you!
}
}
The way I would approach this problem would be to use a map
. Then you can just do the following:
std::map<int, int> counts;
for (const string str : v) {
int length = str.size();
++counts[length];
}
counts[length] will create the element at [length] if it doesn't exist already, and will increment it if it already exists.
Upvotes: 3