字符串

字符串,就是由字符连接而成的序列。

常见的字符串问题包括字符串匹配问题、子串相关问题、前缀/后缀相关问题、回文串相关问题、子序列相关问题等。

字符串各种输入处理

学C++的时候,这几个输入函数弄的有点迷糊;这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所有程序均通过VC 6.0运行)

1、cin
2、cin.get()
3、cin.getline()
4、getline()
5、gets()
6、getchar()

附:cin.ignore();cin.get()//跳过一个字符,例如不想要的回车,空格等字符

1、cin>>

用法 1: 最基本,也是最常用的用法,输入一个数字:

#include <iostream>
using namespace std;
int main (){
    int a,b;
    cin>>a>>b;
    cout<<a+b<<endl;
}
1234567
输入:2[回车]3[回车]
输出:5
12

注意:>> 是会过滤掉不可见字符(如 空格 回车,TAB 等)
cin>>noskipws>>input[j];//不想略过空白字符,那就使用 noskipws 流控制

用法 2: 接受一个字符串,遇“空格”、“TAB”、“回车”都结束

#include <iostream>
using namespace std;

int main (){
    char a[20];
    cin>>a;
    cout<<a<<endl;
}
输入:jkljkljkl
输出:jkljkljkl

输入:jkljkl jkljkl    //遇空格结束
输出:jkljkl

2、cin.get()

用法 1: cin.get(字符变量名)可以用来接收字符

#include <iostream>
using namespace std;

int main (){
    char ch;
    ch=cin.get();        //或者cin.get(ch);
    cout<<ch<<endl;
}
输入:jljkljkl
输出:j

用法 2: cin.get(字符数组名,接收字符数目)用来接收一行字符串,可以接收空格

#include <iostream>
using namespace std;

int main (){
    char a[20];
    cin.get(a,20);
    cout<<a<<endl;
}
12345678
输入:jkl jkl jkl
输出:jkl jkl jkl
12
输入:abcdeabcdeabcdeabcdeabcde (输入25个字符)输出:abcdeabcdeabcdeabcd       (接收19个字符+1个'\0')
1

用法 3: cin.get(无参数)没有参数主要是用于舍弃输入流中的不需要的字符,或者舍弃回车,弥补cin.get(字符数组名,接收字符数目)的不足。

3、cin.getline()

// 接受一个字符串,可以接收空格并输出*

#include <iostream>
using namespace std;
    int main (){    
    char m[20];    
    cin.getline(m,5);    
    cout<<m<<endl;
}
1234567
输入:jkljkljkl
输出:jklj
12

接受5个字符到m中,其中最后一个为’\0’,所以只看到4个字符输出;

如果把5改成20:

输入:jkljkljkl
输出:jkljkljkl
12
输入:jklf fjlsjf fjsdklf
输出:jklf fjlsjf fjsdklf
12
延伸
  • cin.getline()实际上有三个参数,cin.getline(接受字符串m,接受个数5,结束字符)
  • 当第三个参数省略时,系统默认为’\0’
  • 如果将例子中cin.getline()改为cin.getline(m,5,‘a’);当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk

当用在多维数组中的时候,也可以用cin.getline(m[i],20)之类的用法:

#include<iostream>
#include<string>
using namespace std;
int main (){    
    char m[3][20];
    for(int i=0;i<3;i++){
        cout<<"\n请输入第"<<i+1<<"个字符串:"<<endl;
        cin.getline(m[i],20);    
    }
    cout<<endl;
    for(int j=0;j<3;j++)        
        cout<<"输出m["<<j<<"]的值:"<<m[j]<<endl;
}
12345678910111213
请输入第1个字符串:kskr1
1
请输入第2个字符串:kskr2
1
请输入第3个字符串:kskr3
1
输出m[0]的值:kskr1输出m[1]的值:kskr2输出m[2]的值:kskr3
1

4、getline()

// 接受一个字符串,可以接收空格并输出,需包含“#include”

#include<iostream>
#include<string>

using namespace std;
int main (){    
    string str;    
    getline(cin,str);   
    cout<<str<<endl;
}
123456789
输入:jkljkljkl
输出:jkljkljkl
12
输入:jkl jfksldfj jklsjfl
输出:jkl jfksldfj jklsjfl
12

和cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数

5、gets()

// 接受一个字符串,可以接收空格并输出,需包含“#include”

#include<iostream>
#include<string>

using namespace std;

int main (){    
    char m[20];    
    gets(m);            //不能写成m=gets();    
    cout<<m<<endl;
}
12345678910
输入:jkljkljkl
输出:jkljkljkl
12
输入:jkl jkl jkl
输出:jkl jkl jkl
12

类似cin.getline()里面的一个例子,gets()同样可以用在多维数组里面:

#include<iostream>
#include<string>

using namespace std;

int main (){
    char m[3][20];    
    for(int i=0;i<3;i++){        
        cout<<"\n请输入第"<<i+1<<"个字符串:"<<endl;        
        gets(m[i]);    
    }        
    
    cout<<endl;    
    for(int j=0;j<3;j++)        
        cout<<"输出m["<<j<<"]的值:"<<m[j]<<endl;
}
12345678910111213141516
请输入第1个字符串:kskr1
1
请输入第2个字符串:kskr2
1
请输入第3个字符串:kskr3
1
输出m[0]的值:kskr1
输出m[1]的值:kskr2
输出m[2]的值:kskr3
123

自我感觉gets()和cin.getline()的用法很类似,只不过cin.getline()多一个参数罢了;

这里顺带说明一下,对于本文中的这个kskr1,kskr2,kskr3的例子,对于cin>>也可以适用,原因是这里输入的没有空格,如果输入了空格,比如“ks kr jkl[回车]”那么cin就会已经接收到3个字符串,“ks,kr,jkl”;再如“kskr 1[回车]kskr 2[回车]”,那么则接收“kskr,1,kskr”;这不是我们所要的结果!而cin.getline()和gets()因为可以接收空格,所以不会产生这个错误;

6、getchar()

//接受一个字符,需包含“#include”

#include<iostream>
#include<string>
using namespace std;
int main (){
    char ch;    
    ch=getchar();            //不能写成getchar(ch);    
    cout<<ch<<endl;
}
12345678
输入:jkljkljkl
输出:j
12

//getchar()是C语言的函数,C++也可以兼容,但是尽量不用或少用;

常用函数

char a[100]:

1.定义,输入,长度,输出
char str[100] = "abcdef";
char s2[100] = {0};

scanf("%s", s1);//每次读到空格,会自动停止
printf("%s\n", s1);

gets(s1);//可以读一整行带空格的字符
puts(s1);

int len = strlen(str);

2.把字符串转换成整数
string s = "123";
int a = atoi(s.c_str());
char s1[10] = "123";
int a = atoi(s1);

3.判断字母c是不是数字
isdigit(c);
islower(c);
c = toupper(c);

4.字符串拼接
char s1[10] = "123";
char s2[5] = "afs";
strcat(s1, s2);

5.字符串比较:相同输出0,s1>s2输出1,s1<s2输出-1
char s1[10] = "abcdefgh";
char s2[10] = "aaa";
cout << strcmp(s1, s2);

6.复制:把s2的内容复制到s1中
char s1[10] = "abcdefgh";
char s2[10] = "bbbbbb";
strcpy(s1, s2);

7.查找子串
pos = str.find("abc")

8.删除字符串
str.erase(pos, 3);

string a:

1.输入输出
string str1;
cin >> str1;
cout << str1;

getline(cin, str1);
puts(str1.c_str());

不能用:
scanf("%s",&str1);
printf("%s",str1);

2.str1.strcmp(str2)
两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。
若str1 = str2返回0;若str1 > str2 返回正数;若str1<str2 返回负数

string str1 = "abc";
string str2 = "abc";
cout << str1.compare(str2) << endl;//0

3.int lena = str.size();

4.str2.find(str1)
返回str2第一次和str1匹配的下标,否则返回-1
string str1 = "abc";
string str2 = "aaaabc";
cout << str2.find(str1) << endl;

5.可以进行修改
string str1 = "abc";
str1[0] = 'b';
cout << str1 << endl;//bbc

6.转小写
transform(str.begin(), str.end(), str.begin(), ::tolower); 

char数组 常用函数

strlwr(s1)

将字符串 s1 中的所有的大写字母转换为小写字母

#include <bits/stdc++.h>

using namespace std;

int main(int argc, char* argv[]) {
    char s1[20] = "HeLLo WorlD";
    char* s2 = strlwr(s1);
    cout << s2 << endl;  //输出结果为hello world
    return 0;
}

strupr(s1)和strlwr(s1)相反

strstr(s1,s2)

功能:用来定义判断 s2 是否为 s1 的字串
返回值:如果是,则返回 s2 首次在 s1 中首次出现的地址,如果否,则返回NULL

#include <bits/stdc++.h>

using namespace std;

int main(int argc, char* argv[]) {
    char s1[20] = "qwertyuiop";
    char s2[20] = "yuiop";
    char s3[20] = "iods";
    char *s4 = strstr(s1, s2)
    cout << s4 << endl;  //返回 s2 在 s1首次出现的地址 输出yuiop
    cout << strstr(s1, s3) << endl;  //返回NULL
    return 0;
}

strrev(s1)

功能:实现字符反转
说明:只对字符数组有效,对 string 类型是无效的

#include <bits/stdc++.h>

using namespace std;

int main(int argc, char* argv[]) {
    char s1[20] = "hello";
    cout << "反转前: " << s1 << endl;  //输出hello
    strrev(s1);
    cout << "反转后:" << s1 << endl;  //输出olleh

    return 0;
}

strlen

char name[100] = "hello world";
cout << strlen(name) << endl;

strcat

下面两种方式输出结果得到的值是一样的。

char name[100] = "hello world";
char level[100] = "concat test";

char *ret = strcat(name, level);
cout << ret << endl; // 方式1
cout << name << endl; // 方式2

strcpy

char name[10] = "";
char level[100] = "concat test";

strcpy(name, level);
cout << name << endl;

memset

char name[15] = "abc";
char level[100] = "concat test";

memset(name, 'c', 10);
cout << name << endl;

strcmp

比较字符串,相等返回0,s1大返回正数,s2大返回负数

char s1[15] = "abc";
char s2[15] = "abcd";

cout << strcmp(s1, s2) << endl;//-100

stricmp

功 能: 比较字符串大小,忽略大小写
用 法: int stricmp(char *str1, char *str2);

char s1[15] = "abcD";
char s2[15] = "abcd";

cout << stricmp(s1, s2) << endl;//0

string 常用函数

运算符重载

  1. + 和 +=:连接字符串
  2. =:字符串赋值
  3. >、>=、< 和 <=:字符串比较(例如a < b, aa < ab)
  4. ==、!=:比较字符串
  5. <<、>>:输出、输入字符串

注意:使用重载的运算符 + 时,必须保证前两个操作数至少有一个为 string 类型。例如,下面的写法是不合法的:

#include <iostream>
#include <string>
int main()
{
    string str = "cat";
    cout << "apple" + "boy" + str; // illegal!
    return 0;
}

查找

string str;
cin >> str;

str.find("ab");//返回字符串 ab 在 str 的位置
str.find("ab", 2);//在 str[2]~str[n-1] 范围内查找并返回字符串 ab 在 str 的位置
str.rfind("ab", 2);//在 str[0]~str[2] 范围内查找并返回字符串 ab 在 str 的位置

//first 系列函数
str.find_first_of("apple");//返回 apple 中任何一个字符首次在 str 中出现的位置
str.find_first_of("apple", 2);//返回 apple 中任何一个字符首次在 str[2]~str[n-1] 范围中出现的位置
str.find_first_not_of("apple");//返回除 apple 以外的任何一个字符在 str 中首次出现的位置
str.find_first_not_of("apple", 2);//返回除 apple 以外的任何一个字符在 str[2]~str[n-1] 范围中首次出现的位置

//last 系列函数
str.find_last_of("apple");//返回 apple 中任何一个字符最后一次在 str 中出现的位置
str.find_last_of("apple", 2);//返回 apple 中任何一个字符最后一次在 str[0]~str[2] 范围中出现的位置
str.find_last_not_of("apple");//返回除 apple 以外的任何一个字符在 str 中最后一次出现的位置
str.find_last_not_of("apple", 2);//返回除 apple 以外的任何一个字符在 str[0]~str[2] 范围中最后一次出现的位置

//以上函数如果没有找到,均返回string::npos
cout << string::npos;

子串

str.substr(3); //返回 [3] 及以后的子串
str.substr(2, 4); //返回 str[2]~str[2+(4-1)] 子串(即从[2]开始4个字符组成的字符串)

替换

str.replace(2, 4, "sz");//返回把 [2]~[2+(4-1)] 的内容替换为 "sz" 后的新字符串
str.replace(2, 4, "abcd", 3);//返回把 [2]~[2+(4-1)] 的内容替换为 "abcd" 的前3个字符后的新字符串

插入

str.insert(2, "sz");//从 [2] 位置开始添加字符串 "sz",并返回形成的新字符串
str.insert(2, "abcd", 3);//从 [2] 位置开始添加字符串 "abcd" 的前 3 个字符,并返回形成的新字符串
str.insert(2, "abcd", 1, 3);//从 [2] 位置开始添加字符串 "abcd" 的前 [1]~[1+(3-1)] 个字符,并返回形成的新字符串

追加

除了用重载的 + 操作符,还可以使用函数来完成。

str.push_back('a');//在 str 末尾添加字符'a'
str.append("abc");//在 str 末尾添加字符串"abc"

删除

str.erase(3);//删除 [3] 及以后的字符,并返回新字符串
str.erase(3, 5);//删除从 [3] 开始的 5 个字符,并返回新字符串

交换

str1.swap(str2);//把 str1 与 str2 交换

其他

str.size();//返回字符串长度
str.length();//返回字符串长度
str.empty();//检查 str 是否为空,为空返回 1,否则返回 0
str[n];//存取 str 第 n + 1 个字符
str.at(n);//存取 str 第 n + 1 个字符(如果溢出会抛出异常)

实例

查找给定字符串并把相应子串替换为另一给定字符串

string 并没有提供这样的函数,所以我们自己来实现。由于给定字符串可能出现多次,所以需要用到 find() 成员函数的第二个参数,每次查找之后,从找到位置往后继续搜索。直接看代码(这个函数返回替换的次数,如果返回值是 0 说明没有替换):

int str_replace(string &str, const string &src, const string &dest)
{
    int counter = 0;
    string::size_type pos = 0;
    while ((pos = str.find(src, pos)) != string::npos) {
        str.replace(pos, src.size(), dest);
        ++counter;
        pos += dest.size();
    }
    return counter;
}

从给定字符串中删除一给定字串

方法和上面相似,内部使用 erase() 完成。代码:

int str_erase(string &str, const string src)
{
    int counter = 0;
    string::size_type pos = 0;
    while ((pos = str.find(src, pos)) != string::npos) {
        str.erase(pos, src.size());
        ++counter;
    }
    return counter;
}

给定一字符串和一字符集,从字符串剔除字符集中的任意字符

int str_wash(string &str, const string src)
{
    int counter = 0;
    string::size_type pos = 0;
    while ((pos = str.find_first_of(src, pos)) != string::npos) {
        str.erase(pos, 1);
        ++counter;
    }
    return counter;
}

题目

446. 统计单词数

一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。

现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。

注意:匹配单词时,不区分大小写,但要求完全匹配, 即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例 1), 如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例 2)。

输入格式

输入共 2 行。

第 1 行为一个字符串,其中只含字母,表示给定单词。

第 2 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。

输出格式

输出只有一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开, 分别是单词在文章中出现的次数和第一次出现的位置。(即在文章中第一次出现时,单词首字母在文章中的位置,位置从 0 开始)

如果单词在文章中没有出现,则直接输出一个整数 −1。

数据范围

1≤单词长度≤10,
1≤文章长度≤106

输入样例 1:

To
to be or not to be is a question

输出样例 1:

2 0

输入样例 2:

to
Did the Ottoman Empire lose its power at that time

输出样例 2:

-1

思路

关键在于:防止识别在单词内部。

代码

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    string a,b;
    getline(cin,a); // 读入一行
    getline(cin,b);
    transform(a.begin(), a.end(), a.begin(), ::tolower); //转小写
    transform(b.begin(), b.end(), b.begin(), ::tolower);
    a=' ' + a + ' ';  // 防止识别在单词内
    b=' ' + b + ' ';
    int pos=b.find(a); //find()函数找到返回第一次下标,否则返回-1
    int idx=0,res=0;
    if(pos != -1){
        idx=pos;
        while(pos != -1){
            res ++ ;
            pos=b.find(a,pos+1);
        }
    }else{
        cout<<-1<<endl;
        return 0;
    }
    cout<<res<<" "<<idx <<endl;
    return 0;
}

1461 - 反序相等

设N是一个四位数,它的9倍恰好是其反序数(例如:1234 的反序数是4321),求N的值

#include<cstdio>
#include<iostream>
#include<stdlib.h>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
    for (int i = 1000; i <= 1111; i++)
    {    
        string s1 = to_string(i);
        string s2 = to_string(i * 9);
        reverse(s2.begin(), s2.end());
        if (s1.compare(s2)==0)
        {
            cout << i << endl;
        }

    }
    return 0;
}

1014 - 加密算法

编写加密程序,加密规则为:将所有字母转化为该字母后的第三个字母,即A->D、B->E、C->F、……、Y->B、Z->C。小写字母同上,其他字符不做转化。输入任意字符串,输出加密后的结果。

例如:输入”I love 007”,输出”L oryh 007”

#include <bits/stdc++.h>

using namespace std;

int main() {
    char s[105];
    gets(s);
    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        if (s[i] >= 'A' && s[i] <= 'Z') {
            s[i] += 3;
            if (s[i] > 'Z')
                s[i] -= 26;
        } else if (s[i] >= 'a' && s[i] <= 'z') {
            s[i] += 3;
            if (s[i] > 'z')
                s[i] -= 26;
        } else
            continue;
    }
    puts(s);
    return 0;
}

1012 - 字符移动

输入一个字符串,将其中的数字字符移动到非数字字符之后,并保持数字字符和非数字字符输入时的顺序。例如:输入字符串“ab4f35gr#a6”,输出为“abfgr#a4356”。

代码:

法一:sort函数
#include <bits/stdc++.h>

using namespace std;
bool cmp(char a, char b) {
    if (! isdigit(a) && isdigit(b))//如果a不是数字,而b是数字,则返回true 
        return 1;
    else
        return 0;
}

int main() {
    string s;
    cin >> s;
    sort(s.begin(), s.end(), cmp);
    cout << s;
    return 0;
}
法二:分别存储
#include <bits/stdc++.h>

using namespace std;

int main() {
    char s[105] = {0};      //输入的字符串数组
    char num[105] = {0};    //数字数组
    char other[105] = {0};  //其他符号数组
    scanf("%s", s);  //字符串输入用%s 注意字符数组名字就相当于首地址
    int l_id = 0, n_id = 0, o_id = 0;    //定义几个字符数组的下标
    for (int i = 0; i < strlen(s); i++)  // strlen函数是判断字符串长度
    {
        if (s[i] >= '0' && s[i] <= '9') {
            num[n_id++] = s[i];
        } else
            other[o_id++] = s[i];
    }
    printf("%s", other);
    printf("%s\n", num);
    return 0;
}
法三:2次遍历

先输出非字母,再输出字母

#include <bits/stdc++.h>

using namespace std;

int main() {
    char s[105] = {0};
    scanf("%s", s);
    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        if (!isdigit(s[i]))
            printf("%c", s[i]);
    }
    for (int i = 0; i < len; i++) {
        if (isdigit(s[i]))
            printf("%c", s[i]);
    }
    return 0;
}

首字母大写

对一个字符串中的所有单词,如果单词的首字母不是大写字母,则把单词的首字母变成大写字母。 在字符串中,单词之间通过空白符分隔,空白符包括:空格(‘ ‘)、制表符(‘\t’)、回车符(‘\r’)、换行符(‘\n’)。

多组输入

法一

一次读入一整行,包括空格

string, getline(cin, s)

#include <bits/stdc++.h>

using namespace std;

int main() {
    string s;
    while (getline(cin, s)) {
        for (int i = 0; i < s.size(); i++) {
            if ((!i || s[i - 1] == ' ' || s[i - 1] == '\t') && s[i] >= 'a' &&
                s[i] <= 'z')
                s[i] -= 32;
        }
        cout << s << endl;
    }

    return 0;
}

法二:

char s[100],while( gets(s)!=NULL ),cout << s <<endl;

法三:

逐个单词的读,将第一个字母大写

#include <bits/stdc++.h>

using namespace std;

int main() {
    char s[100];
    while (scanf("%s", s) != EOF) {
        if (islower(s[0]))
            s[0] = toupper(s[0]);
        printf("%s ", s);
    }
    return 0;
}

1027 - 删除字符串2

给你一个字符串S,要求你将字符串中出现的所有”gzu”(不区分大小写)子串删除,输出删除之后的S。

就是说出现“Gzu”、“GZU”、“GZu”、”gzU”都可以删除。

#include <bits/stdc++.h>

using namespace std;

int main() {
    string str, str1;
    cin >> str;
    str1 = str;
    int pos = 0;
    transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
    while ((pos = str1.find("gzu")) != -1) {
        str.erase(pos, 3);
        str1.erase(pos, 3);
    }
    cout << str << endl;
    return 0;
}

日志排序***

有一个网络日志,记录了网络中计算任务的执行情况,每个计算任务对应一条如下形式的日志记录:

hs_10000_p 2007-01-17 19:22:53,315 253.035(s)

其中 hs_10000_p 是计算任务的名称,2007-01-17 19:22:53,315 是计算任务开始执行的时间“年-月-日 时:分:秒,毫秒”,253.035(s) 是计算任务消耗的时间(以秒计)

请你写一个程序,对日志中记录计算任务进行排序。

时间消耗少的计算任务排在前面,时间消耗多的计算任务排在后面。

如果两个计算任务消耗的时间相同,则将开始执行时间早的计算任务排在前面。

输入格式

日志中每个记录是一个字符串,每个字符串占一行。最后一行为空行,表示日志结束。

计算任务名称的长度不超过 1010,开始执行时间的格式是 YYYY-MM-DD HH:MM:SS,MMM,消耗时间小数点后有三位数字。

计算任务名称与任务开始时间、消耗时间之间以一个或多个空格隔开。

输出格式

排序好的日志记录。每个记录的字符串各占一行。

输入的格式与输入保持一致,输入包括几个空格,你的输出中也应该包含同样多的空格。

数据范围

日志中最多可能有 1000010000 条记录。
保证不存在开始执行时间和计算任务消耗时间都相同的任务。
开始执行时间保证合法,任务消耗时间不超过 1000010000。

输入样例:

hs_10000_p   2007-01-17 19:22:53,315     253.035(s)
hs_10001_p   2007-01-17 19:22:53,315     253.846(s)
hs_10002_m   2007-01-17 19:22:53,315     129.574(s)
hs_10002_p   2007-01-17 19:22:53,315     262.531(s)
hs_10003_m   2007-01-17 19:22:53,318     126.622(s)
hs_10003_p   2007-01-17 19:22:53,318     136.962(s)
hs_10005_m   2007-01-17 19:22:53,318     130.487(s)
hs_10005_p   2007-01-17 19:22:53,318     253.035(s)
hs_10006_m   2007-01-17 19:22:53,318     248.548(s)
hs_10006_p   2007-01-17 19:25:23,367    3146.827(s)

输出样例:

hs_10003_m   2007-01-17 19:22:53,318     126.622(s)
hs_10002_m   2007-01-17 19:22:53,315     129.574(s)
hs_10005_m   2007-01-17 19:22:53,318     130.487(s)
hs_10003_p   2007-01-17 19:22:53,318     136.962(s)
hs_10006_m   2007-01-17 19:22:53,318     248.548(s)
hs_10000_p   2007-01-17 19:22:53,315     253.035(s)
hs_10005_p   2007-01-17 19:22:53,318     253.035(s)
hs_10001_p   2007-01-17 19:22:53,315     253.846(s)
hs_10002_p   2007-01-17 19:22:53,315     262.531(s)
hs_10006_p   2007-01-17 19:25:23,367    3146.827(s)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <sstream>

using namespace std;

const int N = 10010;

int n;
string logs[N];

int main()
{
    while (getline(cin, logs[n]))
        if (logs[n].size()) n ++ ;
        else break;

    sort(logs, logs + n, [](string& a, string &b) {
        stringstream ssina(a), ssinb(b);
        string sa[4], sb[4];
        for (int i = 0; i < 4; i ++ )
        {
            ssina >> sa[i];
            ssinb >> sb[i];
        }

        if (sa[3] == sb[3]) return sa[1] + sa[2] < sb[1] + sb[2];

        double ta, tb;
        sscanf(sa[3].c_str(), "%lf(s)", &ta);
        sscanf(sb[3].c_str(), "%lf(s)", &tb);
        return ta < tb;
    });

    for (int i = 0; i < n; i ++ )
        cout << logs[i] << endl;

    return 0;
}

作者:yxc
链接:https://www.acwing.com/activity/content/code/content/1706985/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

循环移位

判断a的二进制表示s1是否能由b的二进制表示s2循环移位得到

#include <bits/stdc++.h>

using namespace std;

int main(){
    int a, b;
    while(cin >> a >> b ){
        string s1, s2;
        
        for(int i = 15; i >= 0; i --){
            s1 += to_string(a >> i & 1);
            s2 += to_string(b >> i & 1);
        }
        
        s2 += s2;
        if(s2.find(s1) != -1)cout<< "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1149440709@qq.com

×

喜欢就点赞,疼爱就打赏