今天通过几道题目写一下关于字符串的一些使用与规律以及注意问题:
2140 ISBN码
每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”就是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。

识别码的计算方法如下:

首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。

你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。
输入
输入文件只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。
输出
输出文件共一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。
输入样例

0-670-82162-0

输出样例

0-670-82162-4

代码如下:

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{
    int s;
    char st[20];
    gets(st);
    s=(st[0]-48)*1+(st[2]-48)*2+(st[3]-48)*3+(st[4]-48)*4+(st[6]-48)*5+(st[7]-48)*6+(st[8]-48)*7+(st[9]-48)*8+(st[10]-48)*9;
    s=s%11;
    if(s==10&&st[12]=='X')
    {
        cout<<"Right"<<endl;
    }
    else if(s==st[12]-48)
    {
        cout<<"Right"<<endl;
    }
    else
    {
        for(int i=0;i<strlen(st)-1;i++)
        {
            cout<<st[i];
        }
        if(s!=10)
        cout<<s;
        else
            cout<<"X";
    }
	return 0;
}

**在字符串中数字转移成正常数字的时候,一定要减去48,因为字符串中的数字仍然是以ASCII码为计量单位。即数字0对应字符串中的48。另外字符串中的a对应数字为97,A对应的数字为65,a与A相差32,即小写数字减去大写数字为32。
下面这个题是有关大写字母的转换问题(中间掺杂一些规律问题):

2136 打印图形**
由键盘输入一个大写字母(A 到 Z 中的任意一个),输出如下图所示由相关大写字母组成的图形。所输入的字母一定为输出文件的第一个字符(位于图形的左上角),其余部分的字母构成规律和分布由样例给出。
输入
输入只有一行,仅为一个大写英文字母。
输出
输出文件包含一个如样例所示的图形。注意图形的行数与输入的字母有关,图形的第一行最左侧一定是你输入的那个字母。
输入样例

E

输出样例

EDCBAABCD
 DCBAABC
  CBAAB
   BAA
    A

代码如下:

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int s=0;
    char b,c;
    cin>>c;
    b=c;
    for(int i=65;i<=c-1;i++)
        {
            for(int i=1;i<=s;i++)
                cout<<" ";
            for(char j=b;j>=65;j--)
            cout<<j;
            for(char k=65;k<b;k++)
            cout<<k;
            b--;
            cout<<endl;
            s++;
        }
        for(int i=1;i<=s;i++)
            cout<<" ";
        cout<<"A";
	return 0;
}

2138 单词排序
小红学会了很多英语单词,妈妈为了帮小红加强记忆,拿出纸、笔,把n个单词写在纸上的一行里,让小红看几秒钟后,将这张纸扣在桌子上。妈妈问小红:你能否将这些n个单词按照字典排列的顺序,从小到大写出来?小红按照妈妈的要求写出了答案。现在请你编写程序帮助妈妈检查小红的答案是否正确。注意:所有单词都由小写字母组成,开头字母全都不同,单词两两之间用一个空格分隔。

输入
输入有两行: 第一行仅包含一个正整数n(0<n<27)
第二行包含n个单词,表示妈妈写出的单词,两两之间用一个空格分隔。单个单词长度不超过10。
输出
输出仅有一行:针对妈妈写出的单词,按照字典排列的顺序从小到大排成一行的结果,单词两两之间用一个空格分隔。
输入样例

4
city boy tree student

输出样例

boy city student tree

代码如下:

#include <bits/stdc++.h>
using namespace std;
string a[50];
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
    cout<<a[i]<<" ";
    return 0;
}

在做这个题时,总是无法将字符串输入到字符数组中,因为字符串都是以空格间距输入,而并非回车,因此也无法使用gets(a[i]),getline(cin,a[i])等,因为这些都是输入一行,因此考虑使用scanf();但是总是CE。最后还是用最简单的思路去输入,代码如上。另外在字符串的排序问题上可以选择直接sort排序,也可以选用strcmp来进行比较排序,但是还是sort简单快捷一些。