最近把牛客网华科的题水了一遍,今天把总结的细节东西弄出来整理一下
很久没用c++/c写代码了,一些细节东西还是记记好一点。
(后续可能会因每日刷题而不断更新新的东西。)
主要分为以下5个部分
1数据的输入与输出
2字符串处理(华科的题好像挺多字符串处理的,这里单独拿出来放一个部分)
3包含结构体定义(树)
4需要按照一定规则写的特别的排序,自己写一个比较的函数
5stl模版的使用
pre:
建立c++文件;
头文件声明:
#include<iostream>
#include<vector>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
如果有要用到的大数组可以开在main外
#define maxn 101
int a[maxn][maxn]
1
输入:
①输入多组测试数据
1/while(cin>>n)
2/while(scanf("%d",&n)!=EOF)
输出
②需要输出一大堆数据,末位换行/第二第三个数据前要输出","或其他特殊字符
思路:定义一个bool类型flag标记是否是末位数据或者循环到size()-1;对于最后一一个数据进行特殊处理
2
字符串处理
①c/c++中每个字符串都以字符'\0'作为结尾,这样可以很方便地找到字符串的尾部。
但由于这个特点,每个字符串都有一个额外的字符开销,所以在声明的时候要多预留一个位置。
比如“0123456789”实际存在数组里末位还有一个'\0'字符。
②字符串的输入:
1/while(scanf("%s",str)!=EOF):注意:当读到空格的时候就停止读入
2/char str[1001];
while(gets(str)!=NULL):注意:当读到回车的时候才停止读入,会读入空格;当要处理整段句子的时候可以考虑用gets读入数据到char字符数组中进行处理。
3/声明一个string n,然后while(cin>>n)(用string的时候不可以用gets)
③其他处理
如果用scanf("%s",str)的方式读入一串字符,因为碰到空格的时候就会停止读入;在末尾加入"/0"
如果题目要求对一句话里的单词逐个进行处理的时候,可以利用判断"/0"来辨别是否到一个单词末尾。
例:
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int main() 6 { 7 char n[1000]; 8 while(scanf("%s",n)!=EOF){ 9 int sum=0; 10 int i=0; 11 while(n[i]!='.'&&n[i]!='\0')//这里通过对'\0'进行判断是否到一个单词,用'.'判断是否到句子末尾 12 { 13 14 sum++; 15 i++; 16 } 17 if(n[i]!='.')cout<<sum<<" "; 18 else 19 cout<<sum<<endl; 20 } 21 return 0; 22 }
例 题目:给一行英文句子,只有单词和空格,单词由大小写字母组成。
编程完成以下任务:
统计输出句子中英文字母的个数;统计输出句子单词的个数;查找句子中出现次数最多的字母和次数;当出现最多的字符不止一个的时候都能找到,并输出找到的所有字母和次数。
比较简单的一个题,处理输出时候分号位置要注意,以及用s[i]-'a'||s[i]-'A'的方法找出字母在字母表中的顺序,hash到表中遍历统计即可。
代码如下:
#include<iostream> #include<cstring> using namespace std; int main() { char s[1005]; int abs[26]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; char abc[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; int maxn=0; int i,j=0,num=0,zb,dancinum=0; cout<<"请输入一个英文句子:"<<endl; cin.get(s,1005); //遍历句子统计字母出现次数 while(s[j]!='\0') { if((s[j]>='a'&&s[j]<='z')||(s[j]>='A'&&s[j]<='Z')) { if(s[j]>='a'&&s[j]<='z') zb=s[j]-'a'; else zb=s[j]-'A'; abs[zb]++; num++; } //统计单词出现次数 if(s[j]!=' '&&s[j+1]==' '||s[j]!=' '&&s[j+1]=='\0') dancinum++; j++; } //寻找字母出现的最大次数 for(i=0;i<26;i++) { if(abs[i]>maxn) maxn=abs[i]; } cout<<"字母个数:"<<num<<endl; cout<<"单词个数:"<<dancinum<<endl; cout<<"出现最多的字母:"; int first=1; for(i=0;i<26;i++){ if(abs[i]==maxn) if(first){ cout<<abc[i]; first=0; } else{ cout<<','<<abc[i]; } } cout<<endl; cout<<"出现最多的次数:"<<maxn<<endl; return 0; }
3
结构体定义
一般当题目涉及这种按照一个数据值对一组元组数据进行排序的时候,就要考虑到用结构体定义+自写一个特殊的排序函数对数据进行处理。
①例:
1 #include<stdio.h> 2 #include<string.h> 3 struct A//元组结构体的声明 4 { 5 char name[50]; 6 int age; 7 int score; 8 } A[1000];//声明一个结构体数组 9 int main() 10 { 11 int n=0,i,j; 12 while(scanf("%d",&n)!=EOF) 13 { 14 char name[100]; 15 int age; 16 int score; 17 for(i=0; i<n; i++)//注意对结构体数据输入时,录入名字到char数组中前面不需要加& 18 { 19 scanf("%s%d%d",A[i].name,&A[i].age,&A[i].score); 20 } 21 for(i=0; i<n; i++) 22 { 23 for(j=i; j<n; j++) 24 { 25 if(A[i].score>A[j].score) 26 { 27 age=A[j].age; 28 strcpy(name,A[j].name);//strcpy(a,b):把b字符串复制到a中去 29 score=A[j].score; 30 31 A[j].age=A[i].age; 32 A[j].score=A[i].score; 33 strcpy(A[j].name,A[i].name); 34 35 A[i].age=age; 36 A[i].score=score; 37 strcpy(A[i].name,name); 38 } 39 } 40 } 41 for(i=0; i<n; i++) 42 { 43 for(j=i; j<n; j++) 44 { 45 if(A[i].score==A[j].score) 46 if(strcmp(A[i].name,A[j].name)>0)//strcmp(a,b)对字符串进行比较,若a>b返回正数,a<b返回负数,a=b返回0 47 { 48 age=A[j].age; 49 strcpy(name,A[j].name); 50 score=A[j].score; 51 52 A[j].age=A[i].age; 53 A[j].score=A[i].score; 54 strcpy(A[j].name,A[i].name); 55 56 A[i].age=age; 57 A[i].score=score; 58 strcpy(A[i].name,name); 59 } 60 else if(strcmp(A[i].name,A[j].name)==0) 61 { 62 if(A[i].age>A[j].age) 63 { 64 age=A[j].age; 65 strcpy(name,A[j].name); 66 score=A[j].score; 67 68 A[j].age=A[i].age; 69 A[j].score=A[i].score; 70 strcpy(A[j].name,A[i].name); 71 72 A[i].age=age; 73 A[i].score=score; 74 strcpy(A[i].name,name); 75 } 76 } 77 } 78 79 } 80 for(i=0; i<n; i++) 81 { 82 printf("%s %d %d\n",A[i].name,A[i].age,A[i].score); 83 } 84 } 85 return 0; 86 }
②树的应用
例:
1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct BNode 4 { 5 struct BNode *lchild,*rchild; 6 int data; 7 } BNode,*tree; 8 void Insert(tree root,int x) 9 { 10 11 if(root->data>x) 12 { 13 if(root->rchild) Insert(root->rchild,x); 14 else 15 { 16 tree next=(tree)malloc(sizeof(BNode)); 17 next->data=x; 18 next->lchild=NULL; 19 next->rchild=NULL; 20 root->rchild=next; 21 printf("%d\n",root->data); 22 } 23 } 24 else if(root->data<x) 25 { 26 if(root->lchild) Insert(root->lchild,x); 27 else 28 { 29 tree next=(tree)malloc(sizeof(BNode)); 30 next->data=x; 31 next->lchild=NULL; 32 next->rchild=NULL; 33 root->lchild=next; 34 printf("%d\n",root->data); 35 } 36 } 37 } 38 39 int main() 40 { 41 int n,i,x; 42 while(scanf("%d",&n)!=EOF) 43 { 44 scanf("%d",&x); 45 tree root=(tree)malloc(sizeof(BNode));; 46 printf("-1\n"); 47 root->data=x; 48 root->lchild=NULL; 49 root->rchild=NULL; 50 for(i=1;i<n;++i) 51 { 52 scanf("%d",&x); 53 Insert(root,x); 54 } 55 } 56 return 0; 57 }
4
自写特殊排序+vector数组的动态应用
当涉及要对一大组数据进行排序的时候,可以通过自写一个bool类型函数对特定数据进行大小判断,而后与algorithm的sort函数结合对数据进行排序,可以实现想要的功能。
例:
代码:
1 #include<iostream> 2 #include<vector> 3 #include<string> 4 #include<algorithm> 5 using namespace std; 6 static bool comp(string a,string b)//按照特定的规矩对数据进行排序 7 { 8 if(a.length()<b.length()) 9 return true; 10 if(a.length()>b.length()) 11 return false; 12 if(a.length()==b.length()) 13 return a<b; 14 return false; 15 } 16 int main() 17 { 18 int n; 19 while(cin>>n) 20 { 21 vector<string> vec(n,"");//vector<T> v(n,i)形式,v包含n个值为i的元素 22 for(int i=0;i<n;i++) 23 cin>>vec[i]; 24 sort(vec.begin(),vec.end(),comp);//把vector数组按照特定的函数将元素进行排序 25 for(int i=0;i<n;i++) 26 { 27 cout<<vec[i]<<endl; 28 } 29 } 30 return 0; 31 }