算法学习:每日一题 No.482

482. 密钥格式化

背景:字符串

目的:将字符串重新分组

方法:没有名字的方法

理顺思路

字符串之前被 - 隔开,现在需要重新进行分组,每K个为一组,并且只有第一组字符的个数需要 $\leq K$ 。

首先,要达到每K个字符为一组的目的,我们只需要遍历原字符串,设置计数 $count$ ,每遍历一个非破折号 - 字符,就将 $count + 1$ ,并将该字符加入新的字符串。当 $count \mod K = 0$ 时,加入破折号。

如果从首部开始遍历的话,会使得最后一组字符的个数小于等于K,于是我们只需要从尾部开始遍历就能够满足题意。

这样做还存在一个问题,已经分组结束的字符的开头会多出一个破折号。

因为 string 类中存在 pop_back() 以及 algorithm 库中 reverse() 的存在,我们得以解决问题。

在组合各个字符时,将后续的字符加入字符串尾部,把尾部的破折号通过 pop_back() 的方式去掉,最终反转字符串即可。

#include <algorithm>
#include <string>
using namespace std;
class Solution
{
public:
    string licenseKeyFormatting(string s, int k)
    {
        int length = s.size();
        int count = 0;
        string res;
        for (int i = length - 1; i >= 0; --i)
        {
            char p = s.at(i);
            if (p != '-')
            {
                res.push_back(toupper(p));
                if (++count % k == 0)
                {
                    res.push_back('-');
                }
            }
        }
        if (res.back() == '-')
        {
            res.pop_back();
        }
        reverse(res.begin(), res.end());
        return res;
    }
};
int main(int argc, char const *argv[])
{
    Solution s;
    string res = s.licenseKeyFormatting("5F3Z-2e-9-w", 4);
    return 0;
}

总结

  1. 小写转换为大写的函数原型为 toupper(int __c) ;

  2. 可以将 string 类当作栈来使用,出栈入栈的操作方法为

    pop_back();
    push_back();
    
  3. 获取字符串开始字符和结束字符的方法:

    front();
    back();