1、题目描述
2、解题思路
通过示例可知,所谓的缩写就是对某些子串用子串的长度来代替。
遍历 abbr 的每一个字符:
1、当出现带有前导 0 的数字,则直接 false,例如:friend 缩写成 f04d 就是不符合题意的;
2、abbr 对应位置的字符要和 word 一致,例如:word 的缩写 w2d,其中 d 是第 3 位的字符,两者的第 3 位的字符应该都是 d,否则 false;
3、缩写展开后的长度应该和原单词一致,例如,word 长度为 4,缩写 1or1 展开后长度也是 4,否则 false。
3、解题代码
/**
* Java 实现
**/
class Solution {
public boolean validWordAbbreviation(String word, String abbr) {
char[] chars = abbr.toCharArray();
int num = 0; // 缩写中的数字,不能出现前导0
int next = 0; // 遍历 chars 的指针
for (char c : chars) {
// 如果是数字,则拼接成最后的样子
if (c >= '0' && c <= '9') {
// 前导0数字不合法
if (num == 0 && c == '0') return false;
num = num * 10 + (c - '0');
continue;
}
next = next + num; // 更新指针
// 如果 next 超出了 word 的长度,说明不是 word 的缩写
// 或者,如果 word 和 abbr 在 next 位置的字符不一致,则说明不是 word 的缩写
if (next >= word.length() || (word.charAt(next) != c)) {
return false;
}
next++;
num = 0;
}
return next + num == word.length();
}
}
/**
* C 实现
**/
bool validWordAbbreviation(char *word, char *abbr)
{
int wordLen = strlen(word); // 获取源字符串的长度
int num = 0; // 用于记录缩写字符串 abbr 中的数字部分
int idx = 0; // 指向 word 当前字符的索引下标
char *p = abbr; // 用于遍历 abbr 的指针变量
while(*p != '\0') // 遍历 abbr 的每一个字符
{
char c = *p; // 获取 abbr 当前遍历到的字符
if(c >= '0' && c <= '9') // 当前遍历到的字符是数字
{
if(num == 0 && c == '0') return false; // 数字以 0 开头的不符合缩写要求
num = num * 10 + (int)(c - '0'); // 累计数字 num
p++; // 指向 abbr 下一个字符
continue; // 结束当前循环,进入下一个循环
}
idx = idx + num; // 更新 idx ,即 abbr 当前字符和 word 当前字符对应
if(idx >= wordLen || word[idx] != c) // idx 超过了 wordLen 的有效索引或者对应位置字符不一样
{
return false;
}
idx++; // 更新 word 索引,访问下一个字符
p++; // 更新 abbr 指针,访问下一个字符
num = 0; // 记录数字的临时变量置零
}
return idx + num == wordLen; // 此时 idx + num 表示 word 最后一个索引
}