知识点
输入 和 排序
疑问
关于输入还存在疑惑
代码
未改进代码
/**
1.首尾有空格
2.之间空格不定
**/
#include "bits/stdc++.h"
#include<string>
#include<vector>
using namespace std;
struct myLog{
string str; //原始输入
double end; //结束时间
int ms; //微秒
int totalA;
int totalB;
};
vector<myLog> logs;
string str; //放到外面节省空间
char start[23]; //时间数组
int year; //年份
int month; //月份
int day; //日
int hour; //小时
int minute; //分钟
int s; //秒
//读取空格函数,传地址的
void readbs(int &idx){
while(str[idx] == ' '){
idx++;
}
}
bool cmp(myLog a,myLog b){
if(a.end < b.end){
return true;
}else if(a.end == b.end){
if(a.totalA < b.totalA){
return true;
}else if(a.totalA == b.totalA){
if(a.totalB < b.totalB){
return true;
}else if(a.totalB == b.totalB){
if(a.ms < b.ms){
return true;
}else{
return false;
}
}
}
}
return false;
}
void print(){
for(int i=0;i<logs.size();i++){
cout<<logs[i].str<<endl;
}
}
int main(){
getline(cin,str);
while(str.size()!=0){
myLog l;
l.str = str;
int idx = 0; //表示读取到字符串哪里了
//如果行首有空格,一直读到没有空格
if(str[0] == ' '){
readbs(idx);
}
//开始读取名字
while(str[idx] != ' '){
idx++;
}
//再次读取空格
readbs(idx);
//读入时间数组
for(int i=0;i<23;i++){
start[i] = str[idx++];
}
//将时间输入
sscanf(start,"%d-%d-%d %d:%d:%d,%d",&year,&month,&day,&hour,&minute,&s,&l.ms);
l.totalA = year*10000+month*100+day;
l.totalB = hour*10000+minute*100+s;
//读取空格
readbs(idx);
char end[23]; //用时数组
int len = 0;
//读取结束时间数组
while(str[idx] != '('){
end[len++] = str[idx];
idx++;
}
//将字符串转换成数字
sscanf(end,"%lf",&l.end);
//放入数组
logs.push_back(l);
getline(cin,str);
}
//排序
sort(logs.begin(),logs.end(),cmp);
print();
return 0;
}
改进代码
之前自己对输入处理不太理解,看了别人的代码理解了,改进建议:
- 当使用
scanf("%s",str)
读取字符数组时,%s
是从第一个不是空格和换行的字符开始读入的,以空格和换行结束读入的。 比如:
可以延伸的是,除了输入一行字符串" abc def\n" scanf("%s",str) 得到的str是"abc",它跳过了前面的空格和换行!!!
%c
,其他都会跳过空格和换行的,而%c
会读取空格和换行!《算法笔记》上有写。 - 当使用
gets()
读取字符数组时,它是读取一整行,它是原封不动的把一行保存下来,它以换行结束读入。输入一行字符串" abc def\n" gets(str) 得到的str是" abc def"
- 字符数组除了在声明时可以使用“=”赋值,其他时候都不行:
char str[10] = "hello" //正确 ------------------------------ char str[10]; str = "hello" //错误,得使用strcpy(str,"hello"),是把后面赋给前面
sscanf()
是从左到右匹配,如果没有将str
全部赋值完也没有关系,比如下面的代码中就省略了"(s)"和它后面的空格
理解了上面的概念,就可以对代码进行改进了。
/**
1.首尾有空格
2.之间空格不定
**/
#include "bits/stdc++.h"
#include<string.h>
#include<vector>
using namespace std;
const int maxn = 100;
struct myLog{
char str[maxn]; //原始输入
double end; //结束时间
int ms; //微秒
int totalA;
int totalB;
};
vector<myLog> logs;
char str[maxn]; //放到外面节省空间
char name[20]; //名称
int year; //年份
int month; //月份
int day; //日
int hour; //小时
int minute; //分钟
int s; //秒
bool cmp(myLog a,myLog b){
if(a.end < b.end){
return true;
}else if(a.end == b.end){
if(a.totalA < b.totalA){
return true;
}else if(a.totalA == b.totalA){
if(a.totalB < b.totalB){
return true;
}else if(a.totalB == b.totalB){
if(a.ms < b.ms){
return true;
}else{
return false;
}
}
}
}
return false;
}
void print(){
for(int i=0;i<logs.size();i++){
printf("%s\n",logs[i].str);
}
}
int main(){
//gets()读取一行
gets(str);
while(strlen(str)!=0){
myLog l;
strcpy(l.str,str);
//使用sscanf进行读入
sscanf(str,"%s %d-%d-%d %d:%d:%d,%d %lf",name,&year,&month,&day,&hour,&minute,&s,&l.ms,&l.end);
//方便比较
l.totalA = year*10000+month*100+day;
l.totalB = hour*10000+minute*100+s;
//放入数组
logs.push_back(l);
gets(str);
}
//排序
sort(logs.begin(),logs.end(),cmp);
print();
return 0;
}
反思
见改进建议