「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」。
句子仅由小写字母('a' 到 'z')、数字('0' 到 '9')、连字符('-')、标点符号('!'、'.' 和 ',')以及空格(' ')组成。每个句子可以根据空格分解成 一个或者多个 token ,这些 token 之间由一个或者多个空格 ' ' 分隔。
如果一个 token 同时满足下述条件,则认为这个 token 是一个有效单词:
- 仅由小写字母、连字符和/或标点(不含数字)。
- 至多一个 连字符
'-'。如果存在,连字符两侧应当都存在小写字母("a-b"是一个有效单词,但"-ab"和"ab-"不是有效单词)。 - 至多一个 标点符号。如果存在,标点符号应当位于 token 的 末尾 。
这里给出几个有效单词的例子:"a-b."、"afad"、"ba-c"、"a!" 和 "!" 。
给你一个字符串 sentence ,请你找出并返回 **sentence 中 有效单词的数目 。
示例 1:
输入:sentence = "cat and dog"
输出:3
解释:句子中的有效单词是 "cat"、"and" 和 "dog"
示例 2:
输入:sentence = "!this 1-s b8d!"
输出:0
解释:句子中没有有效单词
"!this" 不是有效单词,因为它以一个标点开头
"1-s" 和 "b8d" 也不是有效单词,因为它们都包含数字
示例 3:
输入:sentence = "alice and bob are playing stone-game10"
输出:5
解释:句子中的有效单词是 "alice"、"and"、"bob"、"are" 和 "playing"
"stone-game10" 不是有效单词,因为它含有数字
示例 4:
输入:sentence = "he bought 2 pencils, 3 erasers, and 1 pencil-sharpener."
输出:6
解释:句子中的有效单词是 "he"、"bought"、"pencils,"、"erasers,"、"and" 和 "pencil-sharpener."
遍历
这道题我们需要直接遍历,我们先找到有多少个token。我们需要通过空格将token分开
const arr = sentence.split(" ")
这样我们就得到了一个或者多个 token ,但是稍后判断的时候我们还需要判断是否为空,因为当多个token中间是两个空格时,这种方法就会将一个空格判断为符合条件。
然后我们就需要根据条件判断,每一个token是否符合条件。
- 仅由小写字母、连字符和/或标点(不含数字)。
所以我们要判断token是否含有数字
我们遍历每一个token得到
for(let i =0;i<token.length;i++){
if(token[i]>="0"&&token[i]<="9") return false
}
- 至多一个 连字符
'-'。如果存在,连字符两侧应当都存在小写字母("a-b"是一个有效单词,但"-ab"和"ab-"不是有效单词)。
根据第二个条件,只允许有至多一个的“-”,并且必须在字符中间,也就是说多余一个,或者在头在尾都不成立。
let hasHyphens = false;
if (word[i] === '-') {
if (hasHyphens === true || i === 0 || i === n - 1 || !isLetter(word[i - 1]) || !isLetter(word[i + 1])) {
return false;
}
其中的isLetter判断是否为字母。
const isLetter = (ch) => {
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') {
return true;
}
return false;
}
- 至多一个 标点符号。如果存在,标点符号应当位于 token 的 末尾 。
最后就是是否有标点符号,有必须在结尾。
if (word[i] === '!' || word[i] === '.' || word[i] === ',') {
if (i !== n - 1) {
return false;
}
}
当出现了上述的标点符号时,必须在结尾。
总结起来就是
var countValidWords = function (sentence) {
const arr = sentence.split(" ")
const len = arr.length
let ans = 0
for (const a of arr) {
if (isValid(a)) ans++
}
return ans
function isValid (word) {
const n = word.length;
let hasHyphens = false;
for (let i = 0; i < n; i++) {
if (word[i] >= '0' && word[i] <= '9') {
return false;
} else if (word[i] === '-') {
if (hasHyphens === true || i === 0 || i === n - 1 || !isLetter(word[i - 1]) || !isLetter(word[i + 1])) {
return false;
}
hasHyphens = true;
} else if (word[i] === '!' || word[i] === '.' || word[i] === ',') {
if (i !== n - 1) {
return false;
}
}
}
return true;
}
};
const isLetter = (ch) => {
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') {
return true;
}
return false;
}
正则表达式
我们再来看一下所需条件
- 没有数字
- “-”前后都是字母
- 标点出现在最后
/^([,.!]|[a-z]+(-[a-z]+)?[,.!]?)$/
|表示也有可能一个token只有标点符号的可能。
var countValidWords = function (sentence) {
return sentence.split(' ').filter(w => /^([,.!]|[a-z]+(-[a-z]+)?[,.!]?)$/.test(w)).length;
};