2047. Number of Valid Words in a Sentence

A sentence consists of lowercase letters (`'a'` to `'z'`), digits (`'0'` to `'9'`), hyphens (`'-'`), punctuation marks (`'!'`, `'.'`, and `','`), and spaces (`' '`) only. Each sentence can be broken down into one or more tokens separated by one or more spaces `' '`.

A token is a valid word if all three of the following are true:

• It only contains lowercase letters, hyphens, and/or punctuation (no digits).
• There is at most one hyphen `'-'`. If present, it must be surrounded by lowercase characters (`"a-b"` is valid, but `"-ab"` and `"ab-"` are not valid).
• There is at most one punctuation mark. If present, it must be at the end of the token (`"ab,"`, `"cd!"`, and `"."` are valid, but `"a!b"` and `"c.,"` are not valid).

Examples of valid words include `"a-b."`, `"afad"`, `"ba-c"`, `"a!"`, and `"!"`.

Given a string `sentence`, return the number of valid words in `sentence`.

Example 1:

```Input: sentence = "cat and  dog"
Output: 3
Explanation: The valid words in the sentence are "cat", "and", and "dog".
```

Example 2:

```Input: sentence = "!this  1-s b8d!"
Output: 0
Explanation: There are no valid words in the sentence.
"!this" is invalid because it starts with a punctuation mark.
"1-s" and "b8d" are invalid because they contain digits.
```

Example 3:

```Input: sentence = "alice and  bob are playing stone-game10"
Output: 5
Explanation: The valid words in the sentence are "alice", "and", "bob", "are", and "playing".
"stone-game10" is invalid because it contains digits.
```

Constraints:

• `1 <= sentence.length <= 1000`
• `sentence` only contains lowercase English letters, digits, `' '`, `'-'`, `'!'`, `'.'`, and `','`.
• There will be at least `1` token.

2047. Number of Valid Words in a Sentence
``````struct Solution;

impl Solution {
fn count_valid_words(sentence: String) -> i32 {
let mut res = 0;
for word in sentence.split_whitespace() {
if Solution::is_valid(word) {
res += 1;
}
}
res
}

fn is_valid(s: &str) -> bool {
let n = s.len();
let mut h_count = 0;
let s: Vec<char> = s.chars().collect();
for i in 0..n {
let c = s[i];
match c {
'a'..='z' => {}
',' | '!' | '.' => {
if i != n - 1 {
return false;
}
}
'-' => {
h_count += 1;
if i == 0 || i == n - 1 {
return false;
}
if !(('a'..='z').contains(&s[i - 1]) && ('a'..='z').contains(&s[i + 1])) {
return false;
}
}
_ => {
return false;
}
};
}
if h_count > 1 {
return false;
}
true
}
}

#[test]
fn test() {
let sentence = "cat and  dog".to_string();
let res = 3;
assert_eq!(Solution::count_valid_words(sentence), res);
let sentence = "!this  1-s b8d!".to_string();
let res = 0;
assert_eq!(Solution::count_valid_words(sentence), res);
let sentence = "alice and  bob are playing stone-game10".to_string();
let res = 5;
assert_eq!(Solution::count_valid_words(sentence), res);
}
``````