2019-10-21 | UNLOCK

2019-9-21-c++算法题输入处理小结

c++算法题输入处理小结

前言

对于刚做算法题的人而言,第一步是先能处理好输入的数据,然后才是开始考虑用什么数据结构和算法去解决问题,前几天为了笔试刷算法题的时候才发现虽然两年前为了acm刷过一个多月的题目,但是现在连基本的字符串输入处理都要调试很久,因此在这里总结一下,以备未来使用。

https://ac.nowcoder.com/acm/contest/320#question OJ在线编程常见输入输出练习场

字符串处理1:单行多个字符排序

题目:

1
对输入的字符串进行排序后输出

输入描述:

1
2
3
输入有两行,第一行n

第二行是n个空格隔开的字符串

输出描述:

1
输出一行排序后的字符串,空格隔开,无结尾空格

示例:

1
2
3
4
5
输入:
5
c d a bb e
输出:
a bb c d e

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

bool cmp(string a,string b){//按从小到大排列
return a<b;
}
int main(){
int n;
string a[100];
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n,cmp);
cout<<a[0];
for(int j=1;j<n;j++){
cout<<" "<<a[j];
}
}

如果给定了字符数量,用for循环就行,cin在遇到空格和回车符的时候会截断。如果没有给定数量,可以用while(cin>>a),遇到输入的时候会自动终止。

字符串处理2:多行多个字符串

题目描述:

1
对输入的字符串进行排序后输出

输入描述:

1
2
多个测试用例,每个测试用例一行。
每行通过空格隔开,有n个字符,n<100

输出描述:

1
对于每组测试用例,输出一行排序过的字符串,每个字符串通过空格隔开

示例:

1
2
3
4
5
6
7
8
输入:
a c bb
f dddd
nowcoder
输出:
a bb c
dddd f
nowcoder

代码:

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
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
using namespace std;

bool cmp(char* a,char* b){
return string(a)<string(b);//char*转string可以直接string(char*)强制转换,根据题意是对字符串进行排序,char*只对字符串第一个字符排序,所以需要转换。
}
int main(){
char a[100];
int count=0;
char* p[100];
while(cin.getline(a,100)){
p[count]=strtok(a," ");//strtok(char * 待分割字符数组,'要分割的字符,可以填入多个,只要遇到其中一个就进行分割')
while(p[count]!=NULL){
count++;
p[count]=strtok(NULL," ");//之后如果还要对原字符串进行分割,就要填入NULL,要对新的字符串进行分割就填入新的字符串。
}
sort(p,p+count,cmp);
cout<<p[0];
for(int j=1;j<count;j++){
cout<<" "<<p[j];
}
cout<<'\n';
count=0;
}
}

这一题第一个难点是每一行的数据是不定长的,所以不能简单地用while(cin>>a),如果不像被空格隔断,我知道的办法里只有cin.getline(char*,int)

C++并没有像python里split那样方便地对字符串进行分割的字符串,只有类似的能进行字符串分割的strtok,strtok只能对字符串数组进行一次分割,也就是分成两半,然后把前一半存到char * 中返回,剩下的一半还会存在strtok的缓存中(我是这么理解的,因为如果还想对原字符数组进行分割,strtok的第一个参数就要为NULL),所以只有第一次调用strtok才需要在第一个参数中填入待分割的char * ,之后都要填入NULL。

字符和数字转换

以下转自https://blog.csdn.net/sinat_40872274/article/details/81367815

1.【字符串转换为数值】

string和数值转换 转换类型
to_string(val) 把val转换成string
stoi(s,p,b) 把字符串s从p开始转换成b进制的int
stol(s,p,b) 把字符串s从p开始转换成b进制的long
stoul(s,p,b) 把字符串s从p开始转换成b进制的unsigned long
stoll(s,p,b) 把字符串s从p开始转换成b进制的long long
stoull(s,p,b) 把字符串s从p开始转换成b进制的unsigned long long
stof(s,p) 把字符串s从p开始转换成float
stod(s,p) 把字符串s从p开始转换成double
stold(s,p) l把字符串s从p开始转换成long double

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <bits/stdc++.h>
#include <map>
using namespace std;
int main(){
string s="222.22";
cout<<"s="<<s<<endl;
int a = 222;
int ot = stoi(s,0,10);
int ol = stol(s,0,10);
float of = stof(s,0);
double od = stod(s,0);
cout<<"ot="<<ot<<endl;
cout<<"ol="<<ol<<endl;
cout<<"of="<<of<<endl;
cout<<"od="<<od<<endl;
return 0;
}

输出:

1
2
3
4
5
s=222.22
ot=222
ol=222
of=222.22
od=222.22

2.【数值转换为字符串】

用stringstream即可把多种数值类型转换为String类型的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main(){
double a = 123.32;
string res;
stringstream ss;
ss << a;
ss >> res;//或者 res = ss.str();
cout<<res;
return 0;
}

输出:

1
123.32

3.【Char数组类型的字符串】

这里是使用C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字和字符串相互转换。

字符串和数值转换 作用
atof(s) 将字符串s[n]转换为双精度浮点型值。
atoi(s) 将字符串s[n]转换为整型值。
atol(s) 将字符串s[n]转换为长整型值。
strtod(s, *p,b) 将字符串s[n]转换为b进制双精度浮点型值,到p停止,并报告不能被转换的所有剩余数字。
strtol(s, *p,b) 将字符串s[n]转换为b进制长整值,到p停止,并报告不能被转换的所有剩余数字。
strtoul(s, *p,b) 将字符串s[n]转换为b进制无符号长整型值,到p停止,并报告不能被转换的所有剩余数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cctype>
#include <cstdio>
#include <cstdlib>
int main(void ) {
char s[100]="1431";
printf("The number integer is %d\n",atoi(s));

double a=123.45;
double b=-1234.56;
char ptr[50];
gcvt(a,5,ptr);
printf("a value=%s\n",ptr);
gcvt(b,6,ptr);
printf("b value=%s\n",ptr);
return 0;
}

输出:

1
2
3
The number integer is 1431
a value=123.45
b value=-1234.56

评论加载中