初学者无痛C转C++

初学者无痛C转C++

文章目录

为什么要转C++

首先,对于C语言,它初见虽然简单,但是深入后确实非常的难并且不方便的。

例如C语言使用排序qsort必须要写排序函数,但是用C++的std::sort就很方便,而且对于一些常见的数据结构C++也有相对应的STL容器如:queue,stack,vector
最重要的还是C++在C++11之前和C语言相差不大,如果仅仅是打算法竞赛那么C++=C + STL,转起语言来几乎完全没有压力

C++语言基础

对于初学者而言,我们只需要记住如下代码

#include<bits/stdc++.h>usingnamespace std;intmain(void){return0;}

初看这个和C语言极为相似除了using namespace std;和#include <bits/stdc++.h>
对于using namespace std;我们只需要记住不需要了解,如果有人想了解的话可以去搜下C++的命名空间

然后对于#include <bits/stdc++.h>是C++的万能头(竞赛专用,你下的gcc里面是没有这个的,需要额外配置),后续内容中如果学习C++只为了打算法竞赛,那么后续所有头文件都不需要记忆

C++如何输入输出

#include<iostream>#include<string>usingnamespace std;intmain(void){int n; string s; cin >> n; cin >> s; cout << n <<"\n"<< s << endl;}

上述头文件的iostream就相当于C的stdio.h,而string是C++特有的字符串对象
其中C输入为scanf而且还需要记住类似于%d,%s之类的格式化符号,而C++之间cin就可以了,输出的话直接cout

C++string相关

对于C语言我们处理字符串很痛苦(虽然C++也很痛苦),但C++处理字符串却比C语言简单多了

以下列举一些本人常用的字符串处理方法

去除前导空格

#include<iostream>#include<string>usingnamespace std;intmain(void){ string s;while(getline(cin , s)){int pos = s.find_first_not_of(" "); s.erase(0, pos); std::cout << s <<"\n";} std::cout <<"hello , world";}

提示:C++的cin会自动去除掉前导空格
如果是去除前导0的话直接把" "换成"0"就可以了

提取和拼接子串

#include<iostream>#include<string>usingnamespace std;intmain(void){ string s ="hello , world";//从第0个位置开始截取长度为5的子串 string s1 = s.substr(0,5);//从第6个位置开始截取后面的所有字符 string s2 = s.substr(6);//将s1和s2拼接位一个字符串 string s3 = s1 + s2;//运行下二者输出的结果相同 cout << s1 << s2 <<"\n"; cout << s3;}

string截取子串的成员函数为substr相关解释已经在注释当中

一些常用的C++操作

C++sort(排序函数的用法)

#include<algorithm>#include<iostream>#include<string>usingnamespace std;boolcomp(int& a ,int& b){return a > b;}intmain(void){int a[1000]={0,1,1,4,5,1,4};//这个sort第一个参数是这是你要排序的起始位置,第二个参数是终止位置sort(a +1, a +1+6);for(int i =1; i <=6; i++) cout << a[i];//C++排序默认的升序 std::cout <<"\n";//如果我们要用降序的话可以添加第三个参数,也就是我们的自定义比较函数sort(a +1, a +1+6, comp);for(int i =1; i <=6; i++) cout << a[i];}

C++的sort排序的时间复杂度是O(nlogn)比大家常用的冒泡排序快速多了,所有如果要有排序的话推荐一直用这个,至于comp函数,我这里使用了&也就是引用,这样可以避免复制数值,但是大家在平时使用时不添加引用符也可以正常运行

数组去重

#include<algorithm>#include<iostream>#include<string>#include<vector>usingnamespace std;intmain(void){//使用原始数组的方法//数组去重需要我们先排序int a[1000]={0,1,1,4,5,1,4};sort(a +1, a +1+6);//这里去重int* pos =unique(a +1, a +1+6);//这里计算去重后的数组个数int new_count = pos -(a +1);for(int i =1; i <= new_count; i++) std::cout << a[i]<<" ";}//如果不打算了解C++进阶相关,这下面部分可以不看#include<algorithm>#include<iostream>#include<vector>intmain(void){//使用vector(动态数组的做法)  std::vector<int>arr ={0,1,1,4,5,1,4};//这里至于为什么使用arr.begin(),这里暂不讲解,在进阶部分再讲解 std::sort(arr.begin()+1, arr.begin()+1+6);//这里返回的是一个迭代器auto pos =unique(arr.begin()+1, arr.begin()+1+6); arr.erase(pos , arr.end());return0;}

unique函数返回的是检查范围的数据,如果有相同的则移到传入的末尾,之后直接计算剩余元素数量后使用去重过后的数组就行了,详细操作见上述代码

二分查找

在这里插入图片描述
#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>#include<map>#include<set>usingnamespace std;intmain(void){//这里为了演示,我这边就直接用有序数组了int a[105];for(int i =1; i <=100; i++) a[i]= i;//查找第一个小于等于25的元素int* lb1 = std::lower_bound(a +1, a +101,25);int index1 = lb1 - a;// 计算索引 std::cout <<"elem is"<<*(lb1)<<" index is"<< index1 << endl;//查找第一个大于25的元素int* lb2 = std::upper_bound(a +1, a +101,25);int index2 = lb2 - a;// 计算索引 std::cout <<"elem is"<<*(lb2)<<" index is"<< index2 << endl;int* result = std::lower_bound(a +1, a +101,101);//二分超出范围的话if(result == a +101){ std::cout <<"lower_bound(101) return a+101\n";// 因为数组中没有不小于101的元素}return0;}

STL容器相关

常见的STL容器使用

这部分设计数据结构,例如:栈,队列,红黑树,二叉搜索树

常见队列

#include<algorithm>#include<iostream>#include<queue>#include<vector>intmain(void){ std::queue<int>q;//这里模拟插入数据for(int i =0; i <10; i++) q.push(i);//一般我们是不知道队列里面的元素个数的,所以我们一般用while语句来处理//这里的empty返回的是一个bool变量,如果不了可以理解为true = 1(判断为真),false = 0(判断为假)while(!q.empty()){//队列可以查看队头和队尾的元素//其中队头的元素是第一个被插入的元素 std::cout << q.front()<<" "<< q.back()<<"\n";//这里默认弹出队头元素 q.pop();}//双端队列和普通队列的区别就是可以弹出和插入元素到队头和队尾的任意一部分 std::deque<int>qu;for(int i =0; i <10; i++){ qu.push_back(i);//qu.push_front(i);}while(!qu.empty()){ std::cout << qu.front()<<" "<< qu.back()<<"\n";//弹出队尾 qu.pop_back();//弹出队首 qu.pop_front();}}

C++的队列使用和声明极为简单,其中内部实现为一个数组,是根据先进先出(FIFO)思想设计的,所有上述操作时间复杂度都为O(1)
如果使用了using namespace std;,那么上述的的"std::"可以去掉

#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>usingnamespace std;intmain(void){ stack<int>s;for(int i =0; i <10; i++) s.push(i);while(!s.empty()){//默认弹出最后一个元素 std::cout << s.top()<<" "; s.pop();}}

栈和队列的使用方式差不多,最具有分辨力的区别是:栈是根据先进后出(FILO)的思想设计的

map(键值对)

键值对又称字典,是一个相互进行映射(一个键对应一个值)的STL容器,内部实现为红黑树或(二叉搜索树),其插入的时间复杂度为O(logn)是一个在算法竞赛中很实用的STL容器

#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>#include<map>usingnamespace std;intmain(void){ std::map<int,int>mp;int temp =114514;for(int i =0; i <10; i++){//插入数据(这两种方法都可以)if(i <4) mp[i]= temp *(10- i);else mp.insert({i , temp *(10- i)});}//遍历mapfor(auto&[key , value]: mp){//这里的key代表第一个也就是键,第二个代表值,这两个可以随意命名 std::cout <<"mp["<< key <<"] = "<< value <<"\n";//遍历是根据键的大小来输出的,也可以自定义排序(属于进阶内容,新手不必要掌握)}//查找操作,其中时间复杂度为O(logn)if(mp.find(2)!= mp.end()) std::cout <<"Yes";if(mp.find(10)== mp.end()) std::cout <<"No"; std::cout <<"\n";int idx =0;while(1){ mp.erase(idx); idx++;if(mp.empty()){ std::cout <<"已弹出所有元素";break;}}return0;}

我们这里只讲map的插入,删除和遍历以及查找这种基础内容

还有一种map是unordered_map,其结构和map很像,这里不再介绍。
unordered_map和map的区别是,map是红黑树,而它的实现为哈希表,查找,插入的速度为O(1),并且unordered_map是无序的

set(集合)

set和map极为相似,你可以把set理解为只有一个value的的map(一般map有键和值),其中时间复杂度和map基本一致,这里不再介绍

#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>#include<map>#include<set>usingnamespace std;intmain(void){ set<int>s;for(int i =0; i <100; i++) s.insert(0); s.insert(5); s.insert(3); s.insert(114514);//set里面是自动有序而且是会自动去重的for(auto i : s) cout << i <<" "; cout <<"\n";if(s.find(3)!= s.end()) cout <<"Yes"<<" ";if(s.find(6)== s.end()) cout <<"No"<<" "; cout <<"\n";//查看集合的大小 cout << s.size()<<"\n";for(auto i : s) s.erase(i); cout << s.size()<<"\n";return0;}

C++进阶相关

标准输入输出加快

 ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

lambda表达式(无名函数)

 std::vector<int>arr ={1,1,4,5,1,4}; std::sort(arr.begin(), arr.end(),[](int& a ,int& b){return a > b;});

这里只不过是将函数换成了lambda表达式

优先对列自定义排序

structNode{int x , y;booloperator<(Node &a)const{return x < a.x;};};intmain(void){ std::priority_queue<Node>q;}

对于我们自定义的结构体它是无法直接比较大小的,那么直接使用operator进行重载,可以使它们在一个陌生的结构体有明确的大小顺序
由于作者赖的写了,这里简单的介绍下优先队列。优先队列就是我们所说的堆,其中内部是二叉搜索树,插入和弹出都是logn的复杂度,堆顶元素默认是最大(最小)元素

stringstream流

#include<vector>#include<string>#include<sstream>#include<iostream>usingnamespace std;intmain(void){//将字符类型转化为整数 std::string s ="1 2 3 4 5 6"; std::vector<int>arr; stringstream stream(s);int num;while(stream >> num){ arr.push_back(num);}for(auto i : arr) cout << i <<" "; cout <<"\n";//将数据为某个字符串分割 string data ="apple,banana,orange,grape"; stringstream ss(data); string fruit;while(getline(ss, fruit,',')) cout << fruit << endl;return0;}

结语

以上内容属于C++基础内容,如果以后有从事C++相关行业的话属于基础中的基础,相反则需要掌握一些C++基础内容,虽然文章中分为了基础和进阶,但即便是只打算打一些简单的算法比赛,以上编码技巧也只属于基础内容

Read more

【AI大模型前沿】蚂蚁开源Ring-lite:边缘计算新选择,2.75B激活参数、小模型大智慧

【AI大模型前沿】蚂蚁开源Ring-lite:边缘计算新选择,2.75B激活参数、小模型大智慧

系列篇章💥 No.文章1【AI大模型前沿】深度剖析瑞智病理大模型 RuiPath:如何革新癌症病理诊断技术2【AI大模型前沿】清华大学 CLAMP-3:多模态技术引领音乐检索新潮流3【AI大模型前沿】浙大携手阿里推出HealthGPT:医学视觉语言大模型助力智能医疗新突破4【AI大模型前沿】阿里 QwQ-32B:320 亿参数推理大模型,性能比肩 DeepSeek-R1,免费开源5【AI大模型前沿】TRELLIS:微软、清华、中科大联合推出的高质量3D生成模型6【AI大模型前沿】Migician:清华、北大、华科联手打造的多图像定位大模型,一键解决安防监控与自动驾驶难题7【AI大模型前沿】DeepSeek-V3-0324:AI 模型的全面升级与技术突破8【AI大模型前沿】BioMedGPT-R1:清华联合水木分子打造的多模态生物医药大模型,开启智能研发新纪元9【AI大模型前沿】DiffRhythm:西北工业大学打造的10秒铸就完整歌曲的AI歌曲生成模型10【AI大模型前沿】R1-Omni:阿里开源全模态情感识别与强化学习的创新结合11【AI大模型前沿】Qwen2.5-Omni:

By Ne0inhk

OpenCode 完全使用指南:开源 AI 编程助手入门到精通

OpenCode 完全使用指南:开源 AI 编程助手入门到精通 本教程基于 OpenCode 官方文档(https://opencode.ai/docs)和 GitHub 仓库(https://github.com/anomalyco/opencode)编写,适合零基础新手入门。 📚 目录 1. 什么是 OpenCode 2. 安装指南 3. 快速开始 4. 配置文件详解 5. Provider 配置 6. TUI 终端界面使用 7. Agent 系统 8. 自定义命令 9. 快捷键配置 10. MCP 服务器 11. LSP

By Ne0inhk
20 万星开源神器 OpenClaw 全解析:程序员 + 视频博主双视角实战体验

20 万星开源神器 OpenClaw 全解析:程序员 + 视频博主双视角实战体验

2026 年初,AI 圈最大的黑马非OpenClaw莫属。这个从 Clawdbot、Moltbot 迭代而来的开源项目,在 GitHub 上星标狂飙至 21.7 万,成为现象级 AI Agent 框架。作为一名拥有 7 年大数据开发经验的程序员,同时也是正在转型视频剪辑的博主,我深度体验了这款工具近一个月,发现它不仅能解放开发者的双手,更能为内容创作带来革命性的效率提升。本文将从技术架构、核心功能、安装部署、双身份实战体验四个维度,带你全面解锁 OpenClaw 的奥秘。 一、核心定位与起源:从 “聊天 AI” 到 “能干活的数字员工” 1. 精准定义 一句话概括:OpenClaw 是本地可自托管、多渠道交互、具备强执行能力的开源 AI Agent 执行引擎。它打破了传统

By Ne0inhk
OpenClaw开源汉化发行版:介绍、下载、安装、配置教程

OpenClaw开源汉化发行版:介绍、下载、安装、配置教程

OpenClaw开源汉化发行版:介绍、下载、安装、配置教程 🎬 背景 🦞 想要一个 100% 私有化、全中文界面的 AI 助手? OpenClaw 汉化版让你零门槛拥有! 这是 GitHub 100,000+ Stars 明星项目的开源中文发行版——不仅做了深度界面汉化(CLI + Dashboard 全中文),更实现了每小时自动同步官方更新,汉化版延迟 < 1 小时,让你既享受中文体验,又不掉队最新功能。 通过 WhatsApp、Telegram、Discord 就能指挥你的 AI 处理邮件、日历、文件,数据完全本地掌控,告别隐私焦虑。无论你是 Docker 老手还是命令行小白,3 步即可上手,本教程覆盖安装、配置、升级、

By Ne0inhk