问题解决:
1.cmark版本不匹配
起初:
然后我又下载了dev-c++
后面我发现CMark如上图也可以!
2.clion无法输出结果
Clion无法输出时候,可以重新开创一个项目,复制过去就解决了!
第1讲:变量的定义与输入输出
-
内容
3部分(头文件+命名空间+main()函数)、变量的定义、cin、cout,scanf、printf
-
练习代码
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
/* int a=1,b=4;
cout<<a+b<<' '<< a*b <<endl;
cout << "Hello, World!" << endl;*/
/* int c=3,d=5;
printf("c+d=%d\nc*d-%d\n",c+d,c*d);*/
/* float f=1.1,h=3.4;
// scanf("%f",&f);
// scanf("%f",&h);
printf("f+h=%.2f\n",f+h);
printf("f*h=%.5f\n",f*h);
浮点数%f
*/
/*int j=6+3*4/2-2;
cout<<j<<endl;
float k=j*10+5/2;//整数相除得整数
float h=j*10+5.0/2.0;
cout<<k<<' '<<h<< endl;
cout<< 5%3<< endl;//取余数
cout<< -5%3<< endl;*/
/*int x=6,y=7;
y+=6;//+-*%/
cout<<x++<<endl;//先引用再自加
cout<<++x<<endl;//先自加再引用
cout<<y<<endl;*/
cout<<'A'+2<<endl;
cout<<char('A'+2)<<endl;
cout<<' '+2<<endl;
int a=3;
printf("%d",a);
return 0;
}
-
习题练习
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
//求和
int a=12,b=27;
cout<<a+b<<endl;
//读取4个数字,计算(A*B-C*D)的值
//求差
int A=7,B=5,C=2,D=3;
printf("%d",A*B-C*D);
}
第2讲:判断语句
-
内容
if...else...的用法、><==、与(&&)或者(||)非(!=)
-
练习代码
#include <iostream>
using namespace std;
int main() {
//循环if,else
int score;
cin>>score;
if(score>=60)
{
cout<<"pass"<<endl;
} else{
cout<<"no"<<endl;
cout<<"fight!"<<endl;
}
//如果>=0输出x,否则-x
int x;
cin >>x;
if(x>=0)
{
cout<<x<<endl;
}else{
cout<<(-x)<<endl;
}
//abc比较大小
int a,b,c;
cin>>a>>b>>c;
if(a>=b&&b>=c){//前面不满足直接短路,不再执行并且(&&)或者(||)非!
cout<<"a is the largest!"<<endl;
}else{
cout<<"a is not the largest!"<<endl;
}
-
习题练习
#include <iostream> using namespace std; int main() { //abc比较大小 int a,b,c; cin>>a>>b>>c; if (a>=b) { if (a>=c){ cout<<"a is the largest!"<<endl; } else{ cout<<"c is the largest!"<<endl; } }else{ if (b>=c){ cout<<"b is the largest!"<<endl; } else{ cout<<"c is the largest!"<<endl; } } //判断是否是闰年 int year; cin>> year; if (year%100==0&&year%400==0||year % 100 != 0&&year % 4 == 0){ cout<<"yes"<<endl; } else { cout << "NO" << endl; } return 0; }
第3讲:循环语句
-
内容
while、do...while、for、break、continue
-
练习代码
#include <iostream> using namespace std; int main() { //while循环 int i; cin>>i; while (i<=5){ cout<<i<<endl; i++; } //求1-10所有立方和 int a=1,sum=0; while (a<=10) { sum=sum+a*a*a; a++; } cout<<sum<<endl; //do...while循环:先执行后判断 //计算1-10的和 int b=0,s=0; //用do...while do{ s+=b; b++; } while (b<=10); cout<<s<<endl; //用while while (b<=10){ s+=b; b++; } cout<<s<<endl;*/ //for(①开始执行;②条件;③表达式(每次都会执行)){} //利用for循环:输出1-10 int s=0; for (int i = 0; i <=10; i++){ s+=i; } cout<<s<<endl; //continue跳过单次,break整体退出 int sum=0; for (int i = 0; i <= 3; i++) { if(i==2)continue; *//* if (i==2)break;*//* sum+=i; } cout<<sum<<endl; return 0; }
第4讲:数组
-
内容
一维数组、二维数组的定义、初始化、调用、memset赋值,sizeof返回字节,memcpy复制
#include <iostream>
#include <cstring>
using namespace std;
int main() {
//程序=逻辑+数据,数组是存储数据的强而有力的手段
/* int c[5]={0};
for (int i = 0; i < 5; ) {
cout<<c[i]<<endl;
i++;
}*/
/*int a[3]={1,5,3};
for (int i = 0; i < 3; i++) {
cout<<a[i]<<endl;
}*/
/* int b[]={1,4,5,7,9};//数组下标从0开始
cout<<b[0]*2<<endl;*/
/* //输入n个数,再逆序输出
int n;
int a[100];
cin>>n;
for (int i = 0; i <n ; i++)
cin>>a[i];
for (int i = n-1; i >=0; i--)
cout<<a[i]<<' ';
cout<<endl;*/
/*
//二维数组定义与初始化
int x[3]={0,1,2};
int y[3][4]={{1,3,4,5},
{1,3,7,9},
{1,2,3,4}};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cout<<y[i][j]<<' ';
}
cout<<endl;
}*/
/*//赋值
int a[10],b[10];
cout<<sizeof a<<endl;//数组中1个占4字节
memset(a,-1,40);//byte为1,一般全部赋值为0/-1
for(int i=0; i< 10;i++){
cout<<a[i]<<' ';
}*/
//复制
/*int a[10],b[10];
//memcpy(目标,原,长度)
memcpy(b,a,sizeof a);
for(int i=0; i< 10;i++){
cout<<a[i]<<' ';
}
cout<<endl;
for(int i=0; i< 10;i++)
cout<<b[i]<<' ';
return 0;*/
}
-
习题练习
#include <iostream> #include <cstring> using namespace std; int main() { //输入一个整数v,输出一个长度为10的数组,数组第一个元素为v,后续每个为上一个的2倍 int a[10],v; cin>>v; for (int i = 0; i < 10; i++) { a[i]=v; cout<<a[i]<<endl; v*=2; } return 0; }
第5讲:字符串
-
内容
字符与整数、字符串的输入输出(fgets、getline)、3个重要的函数(长度strlen、比较大小strcmp、复制strcpy)
-
练习代码
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
int main() {
/*//字符串是计算机与人类沟通的重要手段
//英文常用字符都对应一个-128-127的数字,两者可以相互转化
char c='a';
cout<<(int)c<<endl;
cout<<(char)97<<endl;
//输出128个符号
for (int i = 0; i <128 ; i++) {
cout<<(char)i<<endl;
}
//符号做差,字符可以参与整数运算
printf("%d\n",'h'-'a');*/
/*//字符串就是字符数组+\0.所以字符数组要比字符串的长度多1!
//输入
char a1[]={'c','+','+'};
char a2[]={'c','+','+','\0'};
char a3[]="c++";
cout<<sizeof a1<<'\0'<<sizeof a2<<'\0'<<sizeof a3<<'\0'<<endl;
//输出
char a4[]={'A','B','C','\0'};
cout<<a4<<endl;
cout<<a4+1<<endl;
cout<<a4+2<<endl;*/
/*char a5[100];
scanf("%s",a5);
cin>>a5;
printf("%s\n",a5);
cout<<a5<< endl;*/
/* //读入一行到数组里面变量
char b1[100];
cin>>b1;
cout<<b1<<endl;//遇见空格就停止
fgets(b1,100,stdin);
cout<<b1<<endl;
//读入一行到字符串里面
string b2;
getline(cin,b2);
cout<<b2<<endl;*/
/*char b2[100];
scanf("%s",b2);
puts(b2);
printf("%s",b2);
*/
//3个重要的函数
/*char c[100];
* //strlen求string的length
scanf("%s",c);
cout<<strlen(c)<<endl;*/
/*
* //strcmp比较两个字符串的大小(字典比,例如10<2,第一位),<返回-1,==返回0,>返回1
* char c1[100],c2[100];
scanf("%s%s",c1,c2);
cout<<strcmp(c1,c2)<<endl;*/
/* char c3[100];
scanf("%s",c3);
cout<<strcmp(c3,"abc")<<endl;*/
//string copy,后给前
/* char a4[100],a5[100];
cin>>a4;
strcpy(a5,a4);
printf("%s",a5);*/
return 0;
}
-
习题练习
#include <string.h> using namespace std; int main() { //遍历字符数组中的字符 /*char s1[100]; fgets(s1,100,stdin); for (int i = 0; i < strlen(s1); i++) {//每循环一次strlen都要执行一次 cout<<s1[i]<<endl; }*/ /*char s2[100]; int s3; fgets(s2,100,stdin); s3=strlen(s2);//提前保存,提高效率 for (int i = 0; i < s3; i++) { cout<<s2[i]<<endl; }*/ return 0; }
第6讲:函数
-
内容
函数的定义、调用、参数传递(有/无返回值)、数组传递
-
练习代码
#include <iostream> #include <cstring> #include <string.h> using namespace std; /*//最简单的函数 void output(){ cout<<"yuzuru"<<endl; } int main() { //函数让代码变得更简洁 output(); return 0; */ //函数求和 /*int sum(int s){ int sum=0; for (int i = 0; i <=s; i++) { sum+=i; } return sum; } int main() { int n; cin>>n; int s= sum(n); cout<<s<<endl; return 0;*/ /*//当初始化一个非引用类型的变量时,初始值被拷贝给变量。 // 此时,对变量的改动不会影响初始值。 int f(int x){ x=5; } int main() { int x=10; f(x); cout<<x<<endl; return 0;*/ /*int f(int &x){//加入引用&后,会改变外面的值,可以用于返回多个值 x=5; } int main() { int x=10; f(x); cout<<x<<endl; return 0;*/ /* * 运用&,去交换2个值 * void swap(int &a,int &b){ int t=a; a=b; b=t; } int main(){ int x,y; cin>>x>>y; cout<<x<<' '<<y<<' '<<endl; swap(x,y); printf("change after:\n"); cout<<x<<' '<<y<<' '<<endl; return 0; }*/ /*//输出2个数当中,较大的数值 int max(int a,int b){ if (a>=b){ return a; } else{ return b; } } int main() { int a,b; cin>>a>>b; cout<<max(a,b)<<endl; return 0;*/ /*//函数输出一维数组 int output2(int n,int a[]){ for (int i = 0; i <n ; i++) { cout<<a[i]<<' '<<endl; } } int main() { int b[]={1,2,3,4,5}; output2(5,b); return 0; }*/ //函数输出二维数组 /*int output3(int k,int h,int c[][3]){//第一个可以省略,第二个不可以省略 for (int i = 0; i < k; i++) { for (int j = 0; j < h; j++) { cout<<c[i][j]<<' '; } cout<<endl; } } int main(){ int d[4][3]={ {1,2,3}, {4,5,6}, {7,8,9}, {1,5,7}, }; output3(4,3,d); return 0; }*/ void l(int a,int b=7,int c=3){//默认值必须在后面 cout<<a<<' '<<b<<' '<<c<<endl; } int main(){ l(5);//b不传值就不变! l(5,9);//b传值就改变 return 0; }
第7讲:类、结构体、指针与引用
-
内容
类的定义与调用、指针的读取,修改,引用,链表的遍历,增删改;
-
类和结构体的练习代码
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
//类可以将变量、数组和函数完美打包一起
class person{//结构体struct默认共有public-数据和函数较少,class默认private-复杂的打包
private:
int age,height;//私有只能内部使用
double money=0;
string book[100];
public:
string name;
void say(){
cout<<"I'm"<<name<<endl;
}
int get_age(){
return age;
}
void add_money(double x){
money+=x;
}
};
int main(){
person c;
c.name="yuzuru";
c.add_money(1000);
return 0;
}
//构造函数
struct person{
int age,height;
double money;
person(){}
person(int _age):age(_age){}//更快速的赋值方式
person(int _age,int _height){
age=_age;
height=_height;
}
person(int _age,int _height,double _money){
age=_age;
height=_height;
money=_money;
}
};
int main(){
person p1(18,175,150.00);
person p2={17,180,200.000};
person p3(22,155);
return 0;
}
-
指针的练习代码
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
//char a,b;//堆空间
int main(){
//指针指向存放变量的值的地址。因此我们可以通过指针来修改变量的值。
//查看地址
/*char c='a';//栈空间地址
cout<<(void*)&c<<endl;
char d;
cout<<(void*)&d<<endl;
cout<<(void*)&a<<endl;
cout<<(void*)&b<<endl;
//地址存放变量的下标*/
//读取指针的值
/*int a=10;
int* p=&a;//int*:int类型的指针,p是变量(p是a的地址)
int** q=&p;//p也是一个变量,也有存它的地址
cout<<q<<endl;//q是指针的指针,q为存放指针p的地址
printf("指针输出:");
cout<<*p<< endl;//*p用地址取值
printf("变量输出:");
cout<<a<< endl;
//修改
*p=7;//运用地址修改变量的值,类似通过数组下标修改数组的值
printf("修改后,指针输出:");
cout<<*p<< endl;
printf("修改后,变量输出:");
cout<<a<< endl;*/
//数组也是指针,存放的数组的开始地址
/*int c;
int d[]={1,2,3,4};
cout<<(void*)&c<< endl;
cout<<(void*)d<< endl;//存放首地址
cout<<(void*)&d[0]<<endl;//int包含4个字节
cout<<(void*)&d[1]<<endl;
cout<<(void*)&d[2]<<endl;*/
/* int j1;
int j2[]={1,2,3,4};
int *p1=j2;
cout<<(void*)j2<< endl;
cout<<p1+1<< endl;//不是1变2,是加变量长度,int需要+4
double k1;
double k2[]={1,2,3,4};
double *p2=k2;
cout<<(void*)k2<< endl;
cout<<p2+1<< endl;
long long h1;
long long h2[]={1,2,3,4};
long long *p3=h2;
cout<<(void*)h2<< endl;
cout<<p3+1<< endl;*/
/* //取值可以用指针,也可以用数组
int l[]={1,3,7,4};
int *o=l;
cout<<o<<endl;
cout<<*(o)<<endl;
cout<<o+2<<endl;
cout<<*(o+2)<<endl;
cout<<l<<endl;
cout<<*(l)<<endl;
cout<<l+2<<endl;
cout<<*(l+2)<<endl;*/
//引用
int m=7;
int &n=m;//n为m的别名
cout<<m<<endl;
cout<<n<<endl;
m=9;
cout<<m<<endl;
cout<<n<<endl;
return 0;
}
-
链表的练习代码
#include <iostream> #include <cstring> #include <string.h> using namespace std; //定义一个结构体 struct Node{ int val;//值 Node* next;//指针 Node(int _val):val(_val),next(NULL){//构造函数 } }; int main(){ Node p1=Node(1);//返回一个变量 p1.val;//变量调用 Node* p2=&p1; //合成一步 Node* p= new Node(2);//new 返回地址,new动态开辟一个结构体 p->next=p2;//->指针调用,不是指针就用xx .xx进行调用,指向自己 Node* q= new Node(3);// Node* o=new Node(7); p->next=q;//p2指向q的地址 q->next=o;//链表:p->q->0->null;头结点p,一般存放地址到head中 //如何遍历链表? Node* head=p; for (Node* i=head; i ; i=i->next) {//起为head,终止为0,每次指向下一个结点 cout<<i->val<<endl; } cout<<endl; //如何在链表前面再添加一个节点? Node* a=new Node(1); a->next=head;//把a添加到头结点前面 head=a;//在把头结点的地址移动到a的地址 for (Node* i=head; i ; i=i->next) {//起为head,终止为0,每次指向下一个结点 cout<<i->val<<endl; } cout<<endl; //如何删除一个节点? //链表的删除并不是删除该节点,而是把这个节点跳过,把前面的连接到后面(遍历不到) //所以,必须知道该节点的前后节点 // a->next=q; head->next=head->next->next;//头部连接到头部的下下个 for (Node* i=head; i ; i=i->next) {//起为head,终止为0,每次指向下一个结点 cout<<i->val<<endl; } return 0; }
第8讲:STL、位运算、常用库函数
- https://zhuanlan.zhihu.com/p/344558356(学习素材链接)
-
内容
STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。
组件 | 描述 |
容器(Containers) | 容器是用来管理某一类对象的集合。 C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。 |
算法(Algorithms) | 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。 |
迭代器(Iterators) | |
适配器(Adapters) | |
仿函数(Functors) |
1.vector(矢量)
vecctor是一种「变长数组」,即“自动改变数组长度的数组”。
#include <vector>//要使用vector,需要添加头文件:
-
vector的定义
#include <iostream>
#include <cstring>
#include <vector>//要使用vector,需要添加头文件:
using namespace std;
int main(){
//STL提高C++编写效率的一个利器
//vector(矢量),是一种「变长数组」,即“自动改变数组长度的数组”。
//vector的定义:vector<类型名>变量名;
//类型名可以是int、double、char、struct
// 也可以是STL容器:vector、set、queue。
vector<int> a;
vector<double> b;
vector<char> c;
vector<struct node> node();
vector<vector<int> >e;
//注意:vector<vector<int> > name; >>之间要加空格。
//vector数组就是一个一维数组
// 如果定义成vector数组的数组,那就是二维数组。
//vector<int> array[SZIE]; //二维变长数组
//低维是高维的地址。比如二维数组中,它的一维形式就是地址。
int arr[3][2];//定义一个3行2列的地址
cout<<arr[0]<<endl; //输出arr第1行的地址
cout<<arr[1]<<endl; //输出arr第2行的地址
cout<<arr[2]<<endl; //输出arr第3行的地址
return 0;
}
-
vector容器内元素的访问
2种方式:
(1)通过下标访问
#include <iostream>
#include <cstring>
#include <vector>//要使用vector,需要添加头文件:
using namespace std;
int main(){
vector<int> vi={1,3,4};
vi.push_back(7);//push_back()函数:将一个新的元素加到vector的最后面,
cout<<vi[3]<<endl;// 位置为当前最后一个元素的下一个元素
cout<<vi[2]<<endl;
cout<<vi[1]<<endl;
cout<<vi[0]<<endl;
return 0;
}
(2)通过迭代器访问
迭代器(iterator)可以理解为指针:
vector<类型名>::iterator 变量名;
例如:
vector<int>::iterator it;
vector<double>::iterator it;
比如:
#include <iostream>
#include <cstring>
#include <vector>//要使用vector,需要添加头文件:
using namespace std;
int main(){
vector<int> a;
for (int i = 0; i < 5; i++) {
a.push_back(i+2);//每次添加2,依次添加vector的后面
cout<<a[i]<<" ";
}
cout<<endl;
vector<int>::iterator it=a.begin();//a.begin()返回a的首元素地址
for (int i = 0; i < a.size();i++){
cout<<it[i]<<" ";//it[i] = *(it+i) //这两个写法等价
}
return 0;
}
例外遍历的简单写法:
include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
//vector的迭代器不支持it<v.end()的写法,因此循环条件只能it!=v.end()
for (vector<int>::iterator it=v.begin(); it!=v.end();it++)
{
cout<<*it<<" ";
}
return 0;
}
-
vector常用函数实例解析
后面添加一个push_back(),指定添加insert(),
后面删除一个pop_back(),全部删除clear(),指定删除erase()
长度size()
(1)push_back()
void std::vector<int>::push_back(const int &__x)
push_back(item)就是在vector后面添加一个元素item。
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);//依次存入
}
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
return 0;
}
(2)pop_back()
pop_back()一次删除一个
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
cout<<"pop_back,before:"<<endl;
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
v.pop_back();
cout<<"pop_back,after:"<<endl;
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
return 0;
}
(3)size()
size()返回vector中所含元素的
(4)clear()个数
clear()用于一键清空vector中的所有元素,时间复杂度为O(N),其中N为vector中原属和元素的个数。
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
cout<<"pop_back,before:"<<endl;
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
v.pop_back();
cout<<"pop_back,after:"<<endl;
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
v.clear();
cout<<"clear,after:"<<endl;
cout<<endl;
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<v.size()<<endl;
return 0;
}
(5)insert()
与push_back()在尾部添加元素不同的是,insert()是根据指定位置在vector中插入元素。
insert(__position,__x);
insert(要插入的地址,要插入的元素);
参数:
__position:– A const_iterator into the %vector.
__x:– Data to be inserted.
练习:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
cout<<"pop_back,before:"<<endl;
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
//原来输出为0,1,2,3,4
//在2,3之间添加-1
v.insert(v.begin()+3,-1);
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
return 0;
}
(6)erase()
与clear()简单清空vector不同的是erase(),删除指定位置的元素。
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> v;
for (int i = 0; i < 7; i++)
{
v.push_back(i);
}
cout<<"pop_back,before:"<<endl;
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
//原来输出为0,1,2,3,4
//删除1和区间3,4,5
v.erase(v.begin()+1);
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
v.erase(v.begin()+2,v.begin()+5);
for (int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
return 0;
}
-
vector常见用途
(1)储存数据
vector本身可以作为数组使用,而且在一些元素个数不确定的场合可以很好地节省空间。
(2)用邻接表存储图
使用vector实现邻接表,更为简单。
2.set(集合)
set(集合),是一个内部自动有序且不含重复元素的容器。
被插入set集合后,set内部的元素自动递增排序,并且自动去除了重复元素。
set可以去重。
要使用set,需要添加头文件:
#include <set>
using namespace std;
-
set的定义
像定义变量一样定义set变量:
set<类型名> 变量名;
类型名可以是int、double、char、struct,也可以是STL容器:vector、set、queue。
用例:
set<int> name;
set<double> name;
set<char> name;
set<struct node> name;
set<set<int> > name;//注意:> >之间要加空格
set数组的定义和vector相同:
set<类型名> array[SIZE];
例如:
set<int> arr[10];
-
set容器内元素的访问
set只能通过迭代器(iterator)访问:
set<int>::iterator it;
set<char>::iterator it;
这样,就得到了迭代器it,并且可以通过*it来访问set里的元素。
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main(){
set<int> a;
a.insert(7);
a.insert(5);
a.insert(9);
a.insert(5);
a.insert(5);
a.insert(5);
a.insert(5);
for (set<int>::iterator it = a.begin(); it != a.end(); it++)
{
cout << *it << endl;
}
return 0;
}
-
set常用函数实例解析
(1)insert()
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<char> st;
st.insert('C');
st.insert('B');
st.insert('A');
for (set<char>::iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << endl;
}
return 0;
}
(2)find()
find(value)返回的是set中value所对应的迭代器,也就是value的指针(地址)。
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> st;
for (int i = 1; i <= 3; i++)
{
st.insert(i);
}
set<int>::iterator it = st.find(2); //在set中查找2,返回其迭代器
cout << *it << endl;
// 以上可以直接x携程
cout << *(st.find(2)) << endl;
return 0;
}
(3)erase()
erase()有两种用法:删除单个元素、删除一个区间内的所有元素。
1.删除单个元素
删除单个元素有两种方法:
- st.erase(it),其中it为所需要删除元素的迭代器。时间复杂度为O(1)。可以结合find()函数来使用。
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> st;
st.insert(100);
st.insert(200);
st.insert(200);
st.insert(200);
st.insert(100);
st.insert(300);
// 删除单个元素
st.erase(200);
st.erase(st.find(100)); //利用find()函数找到100,然后用erase删除它
for (set<int>::iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << endl;
}
return 0;
}
2.删除一个区间内的所有元素
st.erase(iteratorBegin , iteratorEnd)可以删除一个区间内的所有元素。
其中iteratorBegin为所需要删除区间的起始迭代器
iteratorEnd为所需要删除区间的结束迭代器的下一个地址
也即是[iteratorBegin,iteratorEnd)
#include <iostream>
#include <set>
using namespace std;
//2.删除一个区间内的所有元素
int main()
{
set<int> st;
st.insert(100);
st.insert(200);
st.insert(600);
st.insert(300);
st.insert(400);
st.insert(500);
st.insert(700);
st.insert(800);
st.insert(900);
set<int>::iterator it;
for (it = st.begin(); it != st.end(); it++)
{
cout << *it<<" ";
}
cout<<endl;
//删除800及之后的(包括800)
set<int>::iterator it1 = st.find(800);
st.erase(it1, st.end());
for (it1 = st.begin(); it1 != st.end(); it1++)
{
cout << *it1<<" ";
}
cout<<endl;
//删除200及前的(不包括200)
set<int>::iterator it2 = st.find(200);
st.erase(st.begin(), it2);
for (it2 = st.begin(); it2 != st.end(); it2++)
{
cout << *it2 <<" ";
}
cout<<endl;
//删除300,400,500
set<int>::iterator it3 = st.find(300);
set<int>::iterator it4 = st.find(600);
set<int>::iterator it5=st.erase(it3, it4);
for (it5 = st.begin(); it5 != st.end(); it5++)
{
cout << *it5 <<" ";
}
cout<<endl;
return 0;
}
学习-《从放弃C语⾔到使⽤C++刷算法的简明教程》by 柳婼-笔记
对照该学习材料对上述进行查漏补缺! (《从C语言转C++简明教程 v5.0+》 – 柳婼 の blog)
1.string:输入、拼接
#include <iostream>
#include <set>
using namespace std;
int main(){
string s1="hello ";
string s2="yuzuru";
string s3=s1+","+s2+"!";//字符串的拼接,用+
cout<<s3<<endl;
cout<<s1.length()<<endl;
cout<<s3.length()<<endl;
string s4;
cin>>s4;//以空格为分割线
cout<<s4<<endl;
cout<<s4.length()<<endl;
string s5;
getline(cin,s5);//包含空格
cout<<s5<<endl;
cout<<s5.length()<<endl;
return 0;
}
2.C++ STL之动态数组vector(⽮量)的使⽤
vector 可以⼀开始不定义⼤⼩,之后⽤ resize ⽅法分配⼤⼩,也可以⼀开始就定义⼤⼩,之后还可以对它插⼊删除动态改变它的⼤⼩.
#include <iostream>
#include <set>
#include <vector>
using namespace std;
int main(){
vector<int> v(10); // 直接定义⻓度为10的int数组
vector<int> v1;//先定义⼀个vector变量v1
v1.resize(8); //然后将⻓度resize为8,默认这8个元素都是0
vector<int> v3(100, 9);// 把100⻓度的数组中所有的值都初始化为9
cout << v[0];
return 0;
}
3.C++ STL之集合set的使⽤
.begin()、end()、insert()、find()、erase()
#include <iostream>
#include <set>
#include <vector>
using namespace std;
int main(){
set<int> s;//定义空集合s
s.insert(1);//insert()插入1
cout<< *(s.begin())<< endl;//.begin() 是⼀个指针,指向容器的第⼀个元素
//*表示对指针取值
for (int i = 0; i <=7; i++) {//生成1,2,3,4,5,6,7
s.insert(i);
}
for (auto it = s.begin(); it!=s.end(); it++) {
cout << *it << " ";// ⽤迭代器遍历集合s⾥⾯的每⼀元素
}
cout << endl << (s.find(2) != s.end()) << endl; // 查找集合s中的值,如果结果等于s.end()表示未找到
s.end();//表示未找到 (因为s.end()表示s的最后⼀个元素的下⼀个元素所在的位置)
cout << (s.find(10) != s.end()) << endl; // s.find(10) != s.end()表示能找到10,
s.erase(1); // 删除集合s中的1这个元素
cout << (s.find(1) != s.end()) << endl; // 这时候元素1就应该找不到啦~返回0.
return 0;
}
4.C++ STL之映射map的使⽤
.begin()、end()、rbegin()、size()
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main(){
map<string,int>m;
m["AA"]=01;//AA-01
m["BBBB"]=07;//BBBB-07
m["CC"]=05;//CC-05
m["dddd"]=03;//dddd-03
m["ee"]=02;//ee-02
cout<<m["BBBB"]<<endl;//返回键值
cout<<m["BB"]<<endl;//如果不存在,就返回0
for (auto it = m.begin(); it != m.end(); it++) {
cout << it->first << "-" << it->second << endl;
}
// 访问map的第⼀个元素,输出它的键和值
cout << m.begin()->first << " " << m.begin()->second << endl;
// 访问map的最后⼀个元素,输出它的键和值
cout << m.rbegin()->first << " " << m.rbegin()->second << endl;
// 输出map的元素个数
cout << m.size() << endl;
m["ee"]=03;//把ee-02修改为ee-03
for (auto it = m.begin(); it != m.end(); it++) {
cout << it->first << "--" << it->second << endl;
}
return 0;
}
5.C++ STL之栈stack的使⽤
栈 stack 在头⽂件 #include <stack> 中,是数据结构⾥⾯的栈~
push()、top()、size()、pop()
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s; // 定义⼀个空栈s
for (int i = 0; i < 1; i++) {
s.push(i+2); // 将元素i压⼊栈s中
}
cout << s.top() << endl; // 访问s的栈顶元素
cout << s.size() << endl; // 输出s的元素个数
s.pop(); // 移除栈顶元素
return 0; }
6.C++ STL之队列queue的使⽤
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int> q; // 定义⼀个空队列q
for (int i = 0; i < 6; i++) {
q.push(i); // 将i的值依次压⼊队列q中
}
cout << q.front() << " " << q.back() << endl; // 访问队列的队⾸元素和队尾元素
cout << q.size() << endl; // 输出队列的元素个数
q.pop(); // 移除队列的队⾸元素
cout << q.front() << " ";
return 0;
}
7.C++ STL之unordered_map和unordered_set的使⽤
8. C++的位运算bitset
#include <iostream>
#include <bitset>
using namespace std;
int main() {
// 初始化⽅式:
// bitset<5> b; 都为0
// bitset<5> b(u); u为unsigned int,如果u = 1,则被初始化为10000
// bitset<5> b(s); s为字符串,如"1101" -> "10110"
// bitset<5> b(s, pos, n); 从字符串的s[pos]开始,n位⻓度
bitset<5>a("1001");//5表示5个⼆进位
bitset<7>b("00101");//""里面只能是0/1
for(int i = 0; i < 5; i++)
cout << a[i];
cout<<endl;
for(int i = 0; i < 7; i++)
cout << b[i];
cout << endl << b.any(); //b中是否存在1的⼆进制位
cout << endl << b.none(); //b中不存在1吗?
cout << endl << b.count(); //b中1的⼆进制位的个数
cout << endl << b.size(); //b中⼆进制位的个数
cout << endl << b.test(2); //测试下标为2处是否⼆进制位为1
cout<<endl;
for(int i = 0; i < 7; i++)
cout << b[i];
cout<<endl;
b.set(4); //把b的下标为4处置1
for(int i = 0; i < 7; i++)
cout << b[i];
cout<<endl;
b.reset(2); //b的下标3处归零
for(int i = 0; i < 7; i++)
cout << b[i];
cout<<endl;
b.reset(); //所有位归零
for(int i = 0; i < 7; i++)
cout << b[i];
cout<<endl;
b.flip(); //b的所有⼆进制位逐位取反
for(int i = 0; i < 7; i++)
cout << b[i];
cout<<endl;
unsigned long c = b.to_ulong(); //b转换为unsigned long类型
return 0;
}
9.C++中的sort函数
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int a, int b) { // cmp函数返回的值是bool类型
return a > b; // 从⼤到⼩排列
}
int main() {
vector<int> v(10);
for (int i = 0; i < 10; i++) {
cin >> v[i];
}
sort(v.begin(), v.end());// 因为这⾥没有传⼊参数cmp,所以按照默认,v从⼩到⼤排列
int arr[10];
for (int i = 0; i < 10; i++) {
cin >> arr[i];
}
sort(arr, arr + 10, cmp); // arr从⼤到⼩排列,因为cmp函数排序规则设置了从⼤到⼩
return 0;
}
10.C++中使⽤sort⾃定义cmp函数
#include <iostream>
using namespace std;
struct stu { // 定义⼀个结构体stu,number表示学号,score表示分数
int number;
int score; }
bool cmp(stu a, stu b) { // cmp函数,返回值是bool,传⼊的参数类型应该是结构体stu类型
if (a.score != b.score) // 如果学⽣分数不同,就按照分数从⼤到⼩排列
return a.score > b.score;
else // 如果学⽣分数相同,就按照学号从⼩到⼤排列
return a.number < b.number; }
// 有时候这种简单的if-else语句,可以直接⽤⼀个C语⾔⾥⾯的三⽬运算符表示~
bool cmp(stu a, stu b) {
return a.score != b.score ? a.score > b.score : a.number < b.number; }
11.关于cctype头⽂件⾥的⼀些函数
#include <iostream>
#include <cctype>
using namespace std;
int main() {
char c='2';
if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {
cout <<c<< " is alpha"; }
else{
cout << c<<" is not alpha";
}
cout<<endl;
//用isalpha
if (isalpha(c)) {
cout << c<<" is alpha";
}else{
cout << c<<" is not alpha";
}
return 0;
}
#include <iostream>
#include <cctype>
using namespace std;
int main() {
char c = 'A';
char b='a';
char t1 = tolower(c); // 将c字符转化为⼩写字符赋值给t
char t2 = tolower(b);//如果c本身就是⼩写字符也没有关系~
cout << t1<<endl; // 此处t为'a'
cout << t2<<endl;
return 0;
}
12.C++11⾥⾯很好⽤的auto声明
auto 是C++11⾥⾯的新特性,可以让编译器根据初始值类型直接推断变量的类型。⽐如这样:
auto x = 100; // x是int变量
auto y = 1.5; // y是double变量
// 本来set的迭代器遍历要这样写:
for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << " "; }
// 现在可以直接替换成这样的写法:
for(auto it = s.begin(); it != s.end(); it++) {
cout << *it << " "; }
13.C++11特性中基于范围的for循环
#include <iostream>
#include <cctype>
using namespace std;
int main() {
int arr[4] = {0, 1, 2, 3};
for (int i : arr)
cout << i << " ";// 输出数组中的每⼀个元素的值,每个元素占据⼀⾏
cout<<endl;
for (int &i : arr) // i为引⽤变量
i = i * 2; // 将数组中的每⼀个元素都乘以2,arr[4]的内容变为了{0, 2, 4, 6}
for (int i : arr)
cout << i <<" ";
return 0;
}
// v是⼀个int类型的vector容器
for (auto i : v)
cout << i << " ";
// 上⾯的写法等价于
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
14.C++11特性中的to_string
#include <iostream>
#include <string>
using namespace std;
int main() {
string s1 = to_string(123); // 将123这个数字转成字符串
cout << s1 << endl;
string s2 = to_string(4.5); // 将4.5这个数字转成字符串
cout << s2 << endl;
cout << s2 + s1 << endl; // 将s1和s2两个字符串拼接起来并输出
printf("%s\n", (s2 + s1).c_str()); // 如果想⽤printf输出string,得加⼀
//个.c_str()
return 0;
}
15.C++11特性中的stoi、stod
#include <iostream>
#include <string>
using namespace std;
int main() {
string str = "123";
int a = stoi(str);
cout << a+11<<endl;
str = "123.44";
double b = stod(str);
cout << b;
return 0;
}