持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
一、题目描述:
给定一个许可密钥字符串 s,仅由字母、数字字符和破折号组成。字符串由 n 个破折号分成 n + 1 组。你也会得到一个整数 k 。
我们想要重新格式化字符串 s,使每一组包含 k 个字符,除了第一组,它可以比 k 短,但仍然必须包含至少一个字符。此外,两组之间必须插入破折号,并且应该将所有小写字母转换为大写字母。
返回 重新格式化的许可密钥 。
示例 1:
输入:S = "5F3Z-2e-9-w", k = 4
输出:"5F3Z-2E9W"
解释:字符串 S 被分成了两个部分,每部分 4 个字符;
注意,两个额外的破折号需要删掉。
示例 2:
输入:S = "2-5g-3-J", k = 2
输出:"2-5G-3J"
解释:字符串 S 被分成了 3 个部分,按照前面的规则描述,第一部分的字符可以少于给定的数量,其余部分皆为 2 个字符。
提示:
- 1 <= s.length <= 10^5
- s 只包含字母、数字和破折号 '-'.
- 1 <= k <= 10^4
二、思路分析:
- 从头到尾开始处理,比官方给的答案要丑一些.
- 在使用下标访问时,一定要先确定当前的下标是否在有效范围内.
- string 函数:
- 返回string的最后一个字符.
- pop_back() remove string的最后一个字符.
- push_back() 将最后一个字符添加到末尾.
- toupper() 会将小写字母变成大写字母. 传入char类型.
三、AC 代码:
class Solution {
public:
string licenseKeyFormatting(string s, int k) {
// 先得到s的长度 n.
// n/k =q ... r;
// if r == 0, q 为总组数; if r != 0, q+1为总组数. 0<r<k;刚好作为第一组.
int dashCount = 0;
for (auto& ch: s){
if (ch == '-'){
dashCount++;
}
}
int len = s.length();
int n = len - dashCount;
// if(n == 0) return "";
// 组
//int q = n / k;
int r = n % k;
string ans;
// "SF3Z-2e-9-w"
int i = 0;
// 先初始化 第一部分.因为第一部分有可能包含少于k个元素.
if (r) {
for (; i< len && r > 0; i++){
if (s[i] != '-'){
if(s[i] >= 'a'&&s[i] <= 'z'){
ans.push_back(s[i] -= 32);
}
else{
ans.push_back(s[i]);
}
r--;
}
}
ans.push_back('-');
}
while(i < len){
// 每个部分有k个元素.
for (int j = 0; i<len && j < k; ){
if (s[i] != '-'){
if(s[i] >= 'a'&&s[i] <= 'z'){
ans.push_back(s[i] -= 32);
}
else{
ans.push_back(s[i]);
}
j++;
}
i++;
}
// 1.某个部分(k个字符)找到后会增加一个 '-'字符;2.当结束时,也会试图增加一个'-'.
if (ans.length() > 0 && ans[ans.length()-1] != '-'){
ans.push_back('-');
}
}
// cout << ans << endl;
if (ans.length() >0){
ans.pop_back();
}
// ans.pop_back();
return ans;
}
};