小米2018校招在线考试-编程题一

题目 名称转换

描述

在C++头文件中可以使用include guard以避免头文件被重复include,譬如:
#ifndef MYHEADER_H_
#define MYHEADER_H_ 
...
#endif 
现在我希望你编写一个程序,将类名按照某种规则转换为include guard所使用的宏。
类名会包含namespace前缀,使用“.”作为分隔符。
被分隔符分开的各个部分称之为组件,组件只会包含大小写字母和数字,且不能以数字开头。
转换规则:
* 在开头和结尾都添加下划线;
* 将“.”转化为下划线;
* 根据下面的规则识别出组件中的单词,并使用下划线将单词进行分隔(具体参照输入输出样例):
    * 第一个大写字母与后面连续的小写字母一起识别为一个单词,如果不以大写字母开头,则直接将连续的小写字母识别为一个单词;
    * 连续的大写字母一起识别为一个单词,但是如果最后一个大写字母后面跟着小写字母,则最后一个大写字母不包含在内;
    * 连续的数字一起识别为一个单词;

输入

多行字符串,每行是一个类名

输出

多行字符串,每行是一个转化后的include guard宏,与输入对应

Example

Input

a
my.ABC
simple.HelloService
MY.ASTParser12

Output

_A_
_MY_ABC_
_SIMPLE_HELLO_SERVICE_
_MY_AST_PARSER_12_

题解

思路

  • 暴力,注意替换和添加’_’的条件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<bits/stdc++.h>

using namespace std;

char str[1000];
char tmp[2000];

int main(){
while(cin>>str)
{
int len=strlen(str);
for(int i=0,j=0;i<len;++i)
{
if(!i) tmp[j++]='_';
if(str[i]=='.')
{
tmp[j++]='_';
}
else if(str[i]>='A'&&str[i]<='Z')
{
if( i && tmp[j-1]!='_' &&
( str[i-1]<'A'||str[i-1]>'Z' ||
str[i-1]>='A'&&str[i-1]<='Z' &&
str[i+1]>='a'&&str[i+1]<='z'
)
)
tmp[j++]='_';
tmp[j++]=str[i];
}
else if(str[i]>='a'&&str[i]<='z')
{
if(i && tmp[j-1]!='_' &&
( str[i-1]<'A' || str[i-1]>'Z' &&
str[i-1]<'a' || str[i-1]>'z'
)
)
tmp[j++]='_';
tmp[j++]=str[i]-32;
}
else if(str[i]>='0'&&str[i]<='9')
{
if(i && tmp[j-1]!='_' &&
( str[i-1]<'0'||str[i-1]>'9' )
)
tmp[j++]='_';
tmp[j++]=str[i];
}
else if(str[i]='_'&&tmp[j-1]!='_')
tmp[j++]='_';
if(i==len-1)
{
if(tmp[j-1]!='_')
tmp[j++]='_';
tmp[j++]=0;
}
}
cout<<tmp<<endl;
}
}