Longest word in a headline
A newspaper's layout tool needs the longest word of every headline to decide on the column width. Complete longest, which takes a slice of words borrowed from the headline and returns one of those words without copying it into a new String. For each input line print the longest word and its length in characters as <word> (<length>); when several words share the greatest length, print the one that appears first. Words are separated by one or more spaces.
Input
One headline per line until end of input; each headline has at least one word, and words are separated by spaces.
Output
One line per headline: <word> (<length>).
Example 1
Input
storm delays harbour ferries
Output
harbour (7)
harbour has 7 letters; every other word is shorter.
Example 2
Input
one two six ten council approves new cycle lane
Output
one (3) approves (8)
In the first headline every word has 3 letters, so the first word wins. The extra spaces in the second headline are not a problem for split_whitespace.
Constraints
- 1 <= number of headlines <= 100
- Each headline has 1-200 characters and at least one word
Hints
Hint 1 of 3
Keep track of the best word so far, starting with words[0], and replace it only when a strictly longer word appears.
Hint 2 of 3
The return type &'a str says the result borrows from the same place the words do, so returning an element of the slice is allowed.
Hint 3 of 3
Compare lengths with chars().count() (or len() for ASCII); use > rather than >= so ties keep the earlier word.
Solution
Show a reference solution and explanation
use std::io::{self, BufRead};
fn longest<'a>(words: &[&'a str]) -> &'a str {
let mut best = words[0];
for &w in words {
if w.chars().count() > best.chars().count() {
best = w;
}
}
best
}
fn main() {
let stdin = io::stdin();
for line in stdin.lock().lines() {
let headline = line.unwrap();
let words: Vec<&str> = headline.split_whitespace().collect();
if words.is_empty() {
continue;
}
let word = longest(&words);
println!("{} ({})", word, word.chars().count());
}
}
Why it works
The signature fn longest<'a>(words: &[&'a str]) -> &'a str is the heart of the exercise. The parameter contains two borrows: the slice itself and the string pieces inside it. The result is one of the pieces, so it must be tied to the pieces' lifetime 'a, not to the shorter-lived slice; without the annotation the compiler cannot tell which of the two you mean and refuses to guess. Because the function returns a borrow, no text is copied: the headline is split once with split_whitespace, the Vec<&str> holds views into it, and the answer is another view. Using strict > in the comparison is what makes ties resolve to the earliest word.