重拾 char 与 ASCII

引入

在leetcode上做的一道题,对其中一个解法有个小坑,可以讨论下
面试题 10.02. 变位词组
先放代码

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        map<string, int> mp;
        vector<vector<string>> ans;
        mp.clear();
        ans.clear();
        int i = 0;
        for(string &str : strs) {
            string status(26, 0);
            for(char ch : str) {
                status[ch - 'a']++;
            }
            if(mp.find(status) != mp.end()) {
                ans[mp[status]].push_back(str);
            } else {
                mp[status] = i++;
                vector<string> v{str};
                ans.push_back(v);
            }
        }
        return ans;
    }
};

这个解法的关键在于如何存每个字符的在一个字符串中出现的次数,并将出现次数的情况当作map的key来使用,当然,我们可以选择用一个大小为26的int数组来存每个字符的次数,但每个字符串的情况不好当作map的key来存(虽然可以对次数做字符拼接,或者次数乘以质数的数学方法,但这里就不讨论了,我们主要讨论由此引出的对ASCII的讨论)
这里我们用了string来存,也就是一个string类型的变量status(26, 0),一个字符串中的每个元素是char类型的,对每个元素ch, 我们做status[ch - ‘a’]++操作,表示第ch-‘a’个字符处存的是字符ch在字符串中出现的次数。而这个次数其实是用char来存的,因为char在计算机中实际上是整数类型。

但这里我们忽略了一点,char在计算机中我们规定是一个字节,即8bit,表示的范围只有-128 ~ 127,所以当一个字符串中某个字符数超过127时,(由于补码的缘故)存在char中的值会变成负数,也就是在status[ch - ‘a’]++的过程中其所存的值只会是0 ~ 127,-128 ~ 0,0 ~ 127的循环,而不是我们预期的129,156 这样可能的实际出现的次数。

结论

ASCII的范围是0 ~ 127,char的范围是-128 ~ 127,好像没啥大关系,都在一个字节范围内。

而ASCII其实是一种很早就被编码到计算机里的一套字符编码规则,也就是编码表,仅有128个对应关系,即当整数在[0, 127]这个范围内时,可以通过内置在计算机中的编码方式,将整数映射成ASCII中的字符,如65在ASCII表中对应A,则以%c的规格打印65时,输出的就是65.

另外,随着中文等其他语言引入计算机,也就多出了后面许多的编码规则如GB2312(中国)、Shift_JIS(日本)、Unicode字符集(大集合)、UTF-8(可变长编码)等字符集编入计算机中,当我们选择某一规则显示当前文本时,编辑器就会以对应的规则去解释每个字符的表示,各字符集会有兼容和不兼容的缘故,因此会有部分乱码或者全篇乱码的现象。

顺手贴个表吧:
Ascii Table

这种入门级的计算机知识,竟然以这种方式让我重拾一番,汗颜~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值