[个人题题解] 逆序输出

题目信息

【团队题目】 T50366 逆序输出

思路与解法

首先我们可以试试无脑逆序输出,然后我们不难发现这只能用于ASCII字符(其他字符会出现乱码,因此样例2直接挂掉)。

如果有点常识的话,你会知道,string的一个char范围是[-128 到 127],这显然不能表示中文字。中文字一般是多个char拼起来形成的,所以一个中文字内部如果被逆序,肯定就乱码了。

所以我们显然需要识别出多个字节的字。不知道UTF-8的编码构造?让我帮你百度一下

百度百科中有下面这张表,我们可以分析一下:

先忽略byte数5和6的(因为显然这些已经不属于最新的UTF-8标准了)。然后找规律。不难发现,一个字的字节数与其第一个字节有下面的关系(length=-1指无效的):

First length
0xxx xxxx 1
10xx xxxx -1
110x xxxx 2
1110 xxxx 3
1111 0xxx 4
1111 1xxx -1

但是char的范围是[-128到127],那么,只要进行有符号转无符号的操作就可以了。这可以使范围变成0到255。

if(c<0) c+=256;

用计算器玩一下上面那个表格,可以整理出下面的信息。

First length condition
0xxx xxxx 1 c<=128
110x xxxx 2 192<=c<=223
1110 xxxx 3 224<=c<=239
1111 0xxx 4 240<=c<=247
others -1 -

也就是说,传入第一个char,就可以知道字符真正的长度了。可以如下实现(强迫症?那就遇到无效字符assert掉)

int classifyChar(int idx) {
    int c=s[idx];
    if(c<0) c+=256;
    if(0<=c && c<=128) return idx+1;
    if(192<=c && c<=223) return idx+2;
    if(224<=c && c<=239) return idx+3;
    if(240<=c && c<=247) return idx+4;
    cerr<<"Wrong char: "<<c<<endl;
    bool char_not_recognized=false;
    assert(char_not_recognized);
    return -1;
}

剩下的实现就简单了。

标准代码

#include<bits/stdc++.h>
using namespace std;

string s;
string t="";

int classifyChar(int idx) {
    int c=s[idx];
    if(c<0) c+=256;
    if(0<=c && c<=128) return idx+1;
    if(192<=c && c<=223) return idx+2;
    if(224<=c && c<=239) return idx+3;
    if(240<=c && c<=247) return idx+4;
    cerr<<"Wrong char: "<<c<<endl;
    bool char_not_recognized=false;
    assert(char_not_recognized);
    return -1;
}

int main() {
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false);

    getline(cin,s);
    for(unsigned l=0;l<s.length();) {
        int r=classifyChar(l);
        t=s.substr(l,r-l)+t;
        l=r;
    }
    cout<<t<<endl;
}

点赞
  1. 肖云帆说道:
    Google Chrome Windows 7

    %%%

发表评论

电子邮件地址不会被公开。必填项已用 * 标注