C++刷题常用
输入输出流
cin读取到换行符或者空格结束,不会读取空格
要读入整行需要使用
scanf("%[^\n]",str);//这里的str需要是一个字符数组,不加取地址符
getchar();//sacnf输入整行之后一定要加一个getchar()读取掉回车
//或者
getline(cin,str);//这里str需要是一个string
注记:输入整行时,若输入string,用getline(cin ,str);
若输入字符数组,用scanf();
string 类
#include<string>
string str;
getline(cin,str);//输入一整行给str
str.empty();//判空
str.size();//判断大小
str1 == str2;
str1 != str2;//string类可以相互比较,对大小写敏感
string s = str.substr(start,n);//截取str中从start下标开始的n个字符的子串,并返回
s = str.substr(start);//截取start下标往后的所有字符
//字符串反转 在<algorithm>库
#include<algorithm>
string str="12345";
reverse(str.begin(),str.end());
cout<<str;//输出str结果为"54321"
str.push_back('d');
str.front();
str.back();
str.pop_back();
如果使用printf输出string对象,需要使用以下方法
printf("%s",str.c_str());
其中c_str()是一个函数,返回一个指向整个c字符串的指针,如果要把string转换成字符数组,必须用strcpy()函数,
string类型之间的比较
string类型之间用 > < 比较,是逐个进行比较的,按照字典序排列,
‘a’ < ‘b’;
#include<iostream>
using namespace std;
#include<string>
int main(){
string s = "12345";
string s2 = "123445";
cout <<( s < s2) << endl;
return 0;
}
//最终结果为false,因为s的第五位,比s2第五位大,就停止比较
所以不能直接用string来进行比较里面的数字大小
把string对象转换成字符数组,相互转换
char c[20];
string s = "1234";
strcpy(c,s.c_str());//因为c_str()返回的是一个临时指针,不能直接将其赋值给c,只能使用strcpy()函数。
char c[] = "123456";
string str = c;//直接赋值即可
cpp中string可以直接通过+组合,
string类和char * 的区别
char* 定义的只是一个指针,不可以通过这个指针改变其指向的字符串。但是string可以
并且char *和字符数组char s[] 也有区别;
char 类型可以转为单个元素的string类
char a = 'b';
string str(1,a);
样例:cpp分割字符串strtok()方法
用到的知识点:读入整行字符串,字符串转换为字符数组,字符数组进行strtok()操作
strtok()是c语言库<string.h>中的方法,
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
int main(){
string str;
getline(cin ,str);
int n = str.size();
char *c = new char[n];
strcpy(c,str.c_str());
char *s = " -";
char *tmp = strtok(c,s);
while(tmp != nullptr){
cout << tmp;
tmp = strtok(nullptr,s);
}
return 0;
}
cpp中的指针相当于java中的引用变量
定义出指针后需要使用new进行分配空间,
new返回的是一个指针变量
cpp的类在new的时候如果没有参数可以不加括号,也可以加
Node *node = new Node;
Node *node = new NOde();
queue操作
#include<queue>
using namespace std;
int main(){
queue<int> myqueue;
myqueue.push(x);//把x存入myqueue
myqueue.front();//返回queue的第一个元素的引用,不删除
myqueue.pop();//删除第一个元素
myqueue.size();
myqueue.empty();//判断空
myqueue.back();//返回最后一个元素
}
stack操作
#include<stack>
using namespace std;
int main(){
stack<int> mystack;
mystack.push(x);
mystack.pop();//弹出栈顶元素
mystack.size();
mystack.empty();
}
vector操作
#include<vector>
using namespace std;
int main(){
vector<int> a;
vector<string> str(10,"xxx");//vector创建时可以初始化
vector<vector<int>> b;//可以嵌套创建,创建二维向量
a.push_back(x);//添加元素
a.pop_back();//删除最后一个元素
a.clear();//清空vector
a.empty();
a.size();
a.data();//vector中的首元素指针,注意是指针,可以用此进行memset操作
}
vector之间可以直接复制
vector<int> a(10,8);
vector<int> b = a;
c++sort函数
sort函数在头文件中
注意:
- sort中有三个参数,起始地址,结束地址(包阔) ,cmp函数排序方法
- cmp函数返回值是bool型
- 如果cmp函数返回true,则代表参数一在参数二前面,注意cmp的两个参数都必须加上引用符
- cmp函数返回的一定是true或者false
- 如果在类中定义cmp函数,需要加上static关键字
#include<iostream>
#include<algorithm>
using namespace std;
#include<string>
class Node{
public:
int a;
int b;
Node(int c=0,int d=0){
a = c;
b = d;
}
};
bool cmp(const Node &a1,const Node &a2){//注意加const修饰,引用并且不可被修改
if(a1.a == a2.a){
return a1.b > a2.b;
}
else{
return a1.a > a2.a;
}
}
/*
struct cmp{
bool operator()(const int &a,const int &b){
return a> b;//重写仿函数,如果返回true,a在b前面
}
};
vector<int> ans;
sort(ans.begin(),ans.end(),cmp());//这样要加cmp()
*/
int main(){
Node arr[20];
for(int i = 0;i<10;i++){
arr[i].a = i;
arr[i].b = i*i - i * 2;
}
for(int i = 10;i<20;i++){
arr[i].a = i-5;
arr[i].b = i*i - i * 2 -10;
}
sort(arr,arr+20,cmp);
for(auto i : arr){
cout << i.a << " " << i.b << endl;
}
return 0;
}
可以和操作符重载并用,
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
struct Student{
string name= "";
int math;
int chinese;
int english;
Student(string name = "",int math = 0,int chinese = 0,int english = 0){
this->name = name;
this->math = math;
this->chinese = chinese;
this->english = english;
}
bool operator>(Student z){
if(math != z.math){
return math > z.math;
}
if(chinese != z.chinese){
return chinese > z.chinese;
}
if(english != z.english){
return english > z.english;
}
return name < z.name;
}
};
bool cmp(Student &a1,Student &a2){
return a1 > a2;
}
int main(){
int n;
cout <<"input the students number: " << endl;
cin >> n;
Student arr[n];
string name;
int math,chinese,english;
for(int i = 0;i<n;i++){
cin >> name >> math >> chinese >> english;
arr[i].name = name;
arr[i].math = math;
arr[i].chinese = chinese;
arr[i].english = english;
}
sort(arr,arr+n,cmp);
cout << "name math chinese english"<<endl;
for(auto i : arr){
cout << i.name << " " << i.math << " " << i.chinese << " " << i.english << endl;
}
return 0;
}
memcpy函数
memcpy函数是内存复制函数有三个参数
memcpy(*new,*old,size);//参数分别是新指针,要复制的指针,新指针分配的大小(字节数)
memcpy(&a,&b,sizeof(a));//使用操作
优先队列(heap堆)
#include<queue> //需要头文件
privrity_queue<int,vector<int>,greater<int> > heap;//第一个参数代表堆中元素类型,第二个参数代表存储容器
heap.push(1);
heap.push(4);
heap.push(2);
heap.empty();
heap.size();
heap.top();//最高优先级元素返回
//元素出堆 从小到大
heap.pop(); // ->1
heap.pop(); // ->2
heap.pop(); //->4
struct cmp{
bool operator()(const int &a,const int &b){
return a> b;//重写仿函数,小顶堆,如果返回true,a、b位置交换,和sort的相反
}
};
privrity_queue<int,vector<int>,cmp> heap;
散列表/map/字典
unordered_map<string,int> dic;
//key->value配对
dic["小李"] = 10001;
dic["小特"] = 10002;
dic["小口"] = 10003;
//从姓名查找学号
dic.find("小李")->second ;// ->10001;
dic.find("小特")->second ;// ->10002;
dic.find("小口")->second ;// ->10003;
deque类(双端队列)
#include<deque>
deque<int> deq;
deq[int index];//访问双向队列中的单个元素
deq.front();//第一个元素
deq.back();//最后一个元素
deq.push_front(x);//头部插入
deq.pop_front();//弹出头部
deq.push_back(x);//尾部插入
deq.pop_back();//尾部弹出
memset() 初始化内存函数
memset只能操作一整片连续的内存,如果是int **需要分层memset 如果是int [] [] 可以直接一个memset
void *memset(void *s, int v, size_t n);//第一个参数是指针,第二个参数是初始值,第三个是大小(字节)