猿创征文|算法学习之路1 重识C++

前言

自CSDN开展编程竞赛以来,每次都参加。在比赛中,收获了很多,也有很多感悟。虽然工作了很多年,代码也写了很多,但基本就是调用开源的API,像算法这种高逻辑的代码编写其实很少。个人对编程语言的认知还停留在10年前。这几次参赛都是用C语言,在比赛中越来越感觉到C语言的不便跟不足。

为什么选择C++

一个语言是否成熟看它是否有丰富的类库。
人工智能,自动运维一般都是用Python,因为有现成的包可以调用。例如要对一个数组进行排序,通过系统自带的排序函数就可以很快的完成,像Java,C++等都有自带的排序函数。如果用C语言,就要自己去实现了,无疑就会额外耗费很多时间,在这分秒必争的比赛中,就会落后于其他人。虽然你并不弱,但是别人有更好的工具,效率比你高,这就是现实。
算法比赛一般用的都是Java,学习Java的人毕竟比较多,并且包含的包也多,可以用的函数也多。但本人是从C/C++走过来到,所以对C++比较容易接受些。对C++的认识还停留在面向对象编程,但在算法比赛中,主要是用C++的容器,以及一些内置函数。随着C/C++11,C/C++14乃至C/C++20标准的到来,更好的特性,更方便的写法。

vector的遍历

C++的一大特点就是有很多容器,比起自己写链表要方便很多。算法比赛中基本用的都是vector容器。已经有很多新写法,我们先看一下。

插入一个元素

通常我们使用push_back来插入一个元素,现在还可以使用emplace_back来插入一个元素,如果容器里存的是类,初始化效率就相差很大,emplace_back比push_back少一次拷贝,详细可百度。

	vector<int> vec;
	vec.push_back(1);
	vec.emplace_back(4);
	......

常规的遍历方式

通过数组大小及下标遍历

	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;

通过iterator指针遍历

	vector<int>::iterator it=vec.begin();
	while(it!=vec.end()){
		cout<<*it<<" ";
		it++;
	}
	cout<<endl;

新型的遍历方式

对有的人来说可能并不新鲜,但对停留在10年前的认知的我来说算是比较新的。
auto指针方式

	auto itauto=vec.begin();
	while(itauto!=vec.end()){
		cout<<*itauto<<" ";
		itauto++;
	}
	cout<<endl;

还有for循环方式,data的数据类型就是int,有点象php里面的foreach

	for(auto data:vec){
		cout<<data<<" ";
	}
	cout<<endl;

倒序遍历

之前一直以为只能用it++,不能用it–,手动试了下是可行的,指向最后,然后遍历到前面

	auto ptr=vec.end();
	while(ptr!=vec.begin()){
		ptr--;
		cout<<*ptr<<" ";
	}
	cout<<endl;

比较正规的倒序遍历,使用rbegin和rend函数

	auto ptr2=vec.rbegin();
	while(ptr2!=vec.rend()){
		cout<<*ptr2<<" ";
		ptr2++;
	}	
	cout<<endl;

排序函数sort的使用

C++中有sort函数,需要包含头文件#include<algorithm>

sort的简单实用

对一个整数数组进行排序

	int a[5] = {1,5,9,7,3};
    sort(a, a + 5);
    sort(b, b + 5,greater<int>());//大的在前

对容器进行排序,int,string都可以

    vector<int> arr = {1,5,9,7,3};
    sort(arr.begin(), arr.end());
    vector<string> verstr={"blue","red","green","black","white"};
	sort(verstr.begin(),verstr.end());

输出结果

1 3 5 7 9
black blue green red white

sort自定义函数使用

通过自定义函数可以实现自己对排序规则的一些判断
例如根据到0点的距离从小到大进行排序

	bool comint(int a,int b){
		return abs(a)<abs(b);
	}
	......
	int c[5] = {-1,2,-3,4,-5};
    sort(c, c + 5,comint); 
    for (int i = 0; i < 5; i++) {
		cout<<c[i]<<' ';
	}
    cout << endl;

输出结果

-1 2 -3 4 -5 

碰到char字符串的排序,需要自定义比较函数,比用C要方便多了。

	bool comstr(const char* a,const char* b){
		return strcmp(a,b)<0;
	}
	......
	const char * str[5]={"blue","red","green","black","white"};
	sort(str,str+5,comstr);
	for (int i = 0; i < 5; i++) {
		cout<<str[i]<<' ';
	}
    cout << endl;

输出结果

black blue green red white

求和/拼接函数accumulate的使用

用中文怎么描述还不怎么清楚,如果是整形就是求和,如果是字符串就是拼接,类型要支持+运算符,不行就用自定义
注意要包含头文件#include<numeric>

accumulate简单使用

注意第三个参数为初始化类

	vector<int> vecint={1,2,3,4,5};
	vector<string> verstr={"ab","cd","ef","gh"};
	int retint = accumulate(vecint.begin(),vecint.end(),0);
    string retstr = accumulate(verstr.begin(),verstr.end(),string(""));
    string retstrx = accumulate(verstr.rbegin(),verstr.rend(),string(""));
	cout<<"retint:"<<retint<<endl;
	cout<<"retstr:"<<retstr<<endl;
	cout<<"retstrx:"<<retstrx<<endl;

输出结果

	retint:15
	retstr:abcdefgh
	retstrx:ghefcdab

accumulate自定义使用

同自定义函数可以实现其他功能
例如通过及格人数,字符串通过特定字符拼接(编程大赛第四届单词逆序)

//统计及格人数
int funcint(int result,int data){
	if(data>=60){
		result++;
	}
	return result;
}
//字符串用空格分隔
string funcstring(string result,string data){
	if(!result.empty()){
		result+=" ";
	}
	result+=data;
	return result;
}
......
	vector<int> vecint2={60,70,55,45,80};
	vector<string> verstr2={"I","am","a","boy!"};
	int retint2 = accumulate(vecint2.begin(),vecint2.end(),0,funcint);
    string retstr2 = accumulate(verstr2.rbegin(),verstr2.rend(),string(""),funcstring);
	cout<<"retint2:"<<retint2<<endl;
	cout<<"retstr2:"<<retstr2<<endl;

输出结果

	retint2:3
	retstr2:boy! a am I

总结

C++确实有很多方便的函数,做起题来就方便不少。例如最后一个例子,可以解决编程大赛第四届单词逆序这道题,通过将读取的单词一个一个的放入容器,再通过逆序函数,自定义间隔符就行了。用C语言也可以做这道题,简单点就是从末尾查找空格,从后往前输出,如果自己用链表那耗时就更长了,相比之下,用C++是比较简洁,快速的。如果是统计单词是否重复出现,用C语言就没C++那么方便了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值