北大信科机试练习之基础字符串

试题集 1.7 基础编程之字符串(30-27)

30 字符环

描述

有两个由字符构成的环。请写一个程序,计算这两个字符环上最长连续公共字符串的长度。例如,字符串“ABCEFAGADEGKABUVKLM”的首尾连在一起,构成一个环;字符串“MADJKLUVKL”的首尾连在一起,构成一个另一个环;“UVKLMA”是这两个环的一个连续公共字符串。

输入

一行,包含两个字符串,分别对应一个字符环。这两个字符串之间用单个空格分开。字符串长度不超过255,且不包含空格等空白符。

输出

输出一个整数,表示这两个字符环上最长公共字符串的长度。

样例输入
ABCEFAGADEGKABUVKLM MADJKLUVKL

样例输出
6

思考与做题时遇到的错误:

  1. 字符串收尾相接,首先想到取模,再想到字符串*2再拼接到源字符串后
  2. 长度最长为最短字符串的长度
  3. 遇到的错误:在循环的内部,不要更改循环变量的值

代码:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
   string str1, str2;
   cin >> str1 >> str2;
   int len1 = str1.length();
   int len2 = str2.length();
   int len = min(len1, len2);

   str1 += str1;
   str2 += str2;

   int ans = 0, temp;
   for(int i = 0;i < len1;i ++){
       for(int j = 0;j < len2;j ++){
           temp = 0;
           int x = i;int y = j;
           while(str1[x] == str2[y] && temp < len){
               x ++;y ++;temp ++;
           }
           if(temp > ans)
               ans = temp;
       }
   }
   cout << ans;
}

29 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号码(包括分隔符“-”)。

样例输入
样例 #1:
0-670-82162-4
样例 #2:
0-670-82162-0

样例输出
样例 #1:
Right
样例 #2:
0-670-82162-4

思考与做题时遇到的错误:

  1. 字串分割,用一个变量记录当前已经分割了多少
  2. 注意字符和数字之间的转换
  3. 审题一定要注意

代码:

#include <iostream>
#include <string>
using namespace std;

int main()
{
   string input;
   cin >>input;

   int sum = 0, cnt = 0, order = 1;
   int check;
   int len = input.length();
   string substr = "";
   for(int i = 0;i < len;i ++){
       if(cnt < 3){
           substr += input[i];
           if(input[i] == '-')
               cnt ++;
           else{
               sum += (input[i] + 0 - '0')* order;
               order ++;
           }
       }else{
           if(input[i] == 'X'){
               check = 10;break;
           }
           else
               check = input[i] + 0 - '0';
       }
   }

   if(sum % 11 == check)
       cout << "Right" << endl;
   else{
       if(sum % 11 == 10)
           cout << substr << "X" << endl;
       else
           cout << substr << sum % 11 << endl;
   }
       
}

28 单词倒排

描述

编写程序,读入一行英文(只包含字母和空格,单词间以单个空格分隔),将所有单词的顺序倒排并输出,依然以单个空格分隔。

输入
输入为一个字符串(字符串长度至多为100)。
输出
输出为按要求排序后的字符串。

样例输入
I am a student

样例输出
student a am I

思考与做题时遇到的错误:

  1. 按自己的方法分割的时候,注意字符串的最后以为要单独进行一个加入处理
#include <string>
#include <stack>
#include <iostream>
using namespace std;

int main()
{
    string in;
    getline(cin, in);
    stack<string> S;

    int len = in.length();
    string sub = "";
    for(int i = 0;i < len;i ++){
        if(in[i] != ' '){
            sub += in[i];
        }else{
            S.push(sub);
            sub = "";
        }
    }
    S.push(sub);//重要!!!这个地方老是忘记处理

    while(!S.empty()){
         cout << S.top();
         S.pop();
         cout << " ";
    }

}

27 单词倒排

描述
输入一个句子(一行),将句子中的每一个单词翻转后输出。

输入
只有一行,为一个字符串,不超过500个字符。单词之间以空格隔开。
输出
翻转每一个单词后的字符串,单词之间的空格需与原文一致。

样例输入
hello world

样例输出
olleh drlow

#include <iostream>
#include <string>
using namespace std;

int main()
{
    char ch;
    string sub = "";
    string in;
    getline(cin, in);
    int len = in.length();
    for(int i = 0;i < len;i ++){
        if(in[i] != ' ')
            sub += in[i];
        else{
            for(int j = sub.length() - 1;j >=0;j --)
                cout << sub[j];
            cout << in[i];
            sub = "";
        }
    }
    for(int j = sub.length() - 1;j >=0;j --)
                cout << sub[j];
}

25 最长最短字符

描述

输入1行句子(不多于200个单词,每个单词长度不超过100),只包含字母、空格和逗号。单词由至少一个连续的字母构成,空格和逗号都是单词间的间隔。
试输出第1个最长的单词和第1个最短单词。

输入
一行句子。
输出
两行输出:
第1行,第一个最长的单词。
第2行,第一个最短的单词。

样例输入
I am studying Programming language C in Peking University
样例输出
Programming
I

提示
如果所有单词长度相同,那么第一个单词既是最长单词也是最短单词。

思考与做题时遇到的错误:

  1. substr(int start, int length) 函数第二个参数是字符串的长度
  2. 字符串操作时,如果是空格分割处理的,文本最后一个片段容易不受处理,这时可在字符串最后加一个空格
  3. 表示空格字符,要用单引号,不是双引号
#include <iostream>
#include <string>
using namespace std;

int main()
{
   string in;
   getline(cin, in);

   in += " ";//手动在文本串的最后加一个空格
   int len = in.length();
   string maxstr = "", minstr = "";
   int maxlen = 0, minlen = 200;
   int start = 0, end = 0;
   for(int i = 0;i < len;i ++){
       if(in[i] != ' ' && in[i] != ','){
           end ++;
       }else{
           if(end - start > maxlen){
               maxlen = end - start;
               maxstr = in.substr(start, end -  start);
           }
           if(end != start && end - start < minlen){
               minlen = end - start;
               minstr = in.substr(start, end - start);
           }
           start = i + 1;//start保存有效单词的第一位
           end = start;//end保存有效单词的最后一位
       }
   }
   cout << maxstr << endl << minstr << endl;
   return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值