一些常见基础

目录

0,最基础的关于子函数的传入

1,关于string:

2,最大公约数:

3,int与char之间的转换

4,vector的使用

5,哈希表的使用与“增删改查”

补充:关于迭代器

6,指针p

7,链表

链表的快慢指针技巧

链表的创建节点与修改!!!!!!!!!!!

8,关于栈和队列的知识:

堆:

优先队列:

9,牛客网的输入输出样式:

输入:

(1)cin

(2)getline()

(3)getchar()

输出:

使用sort函数进行排序(自定义)


0,最基础的关于子函数的传入

#include <bits/stdc++.h>

using namespace std;
void x(int &a, int &b) {
	b = a;
	return;
}

int main() {
	int a = 1;int b = 2;
	x(a, b);
	cout << a << " " << b << endl;
	return 0;
}

这样输出的是1 1

void x(int a,int b){}

这样输出的就是1 2(

即使用&传入指针会改变值,直接传入不会改变值

1,关于string:

C++中的String的常用函数用法总结_string函数-CSDN博客

string是一个数组,其中的每一个元素都是char类型,即str[i]是一个char

string str:生成空字符串

string s(str):生成字符串为str的复制品

string s(str, strbegin,strlen):将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值

string s(cstr, char_len):以C_string类型cstr的前char_len个字符串作为字符串s的初值

string s(num ,c):生成num个c字符的字符串

string s(str, stridx):将字符串str中从下标stridx开始到字符串结束的位置作为字符串初值
    string str1;               //生成空字符串
    string str2("123456789");  //生成"1234456789"的复制品
    string str3("12345", 0, 3);//结果为"123"
    string str4("012345", 5);  //结果为"01234"
    string str5(5, '1');       //结果为"11111"
    string str6(str2, 2);      //结果为"3456789"

size()和length():返回string对象的字符个数,他们执行效果相同。
cout << "size=" << s.size() << endl;
cout << "length=" << s.length() << endl;

插入:push_back() 和 insert()
s1.push_back('a');
// insert(pos,char):在制定的位置pos前插入字符char
s1.insert(s1.begin(),'1');

提取:substr
string s="ABAB";
cout << s.substr(2) <<endl ; //输出AB
cout << s.substr(0,2) <<endl ; //同上,从下标0开始,提取两个

拼接:append() 和 + 操作符
string s1("abc");
s1.append("def"); // s1:abcdef
string s2 = "abc";
/*s2 += "def";*/
string s3 = "def";
s2 += s3.c_str(); // s2:abcdef

删除:erase()
string s1 = "123456789";
// s1.erase(s1.begin()+1);              // 结果:13456789
// s1.erase(s1.begin()+1,s1.end()-2);   // 结果:189

查找:find/rfind
    string s("dog bird chicken bird cat");

    //字符串查找-----找到后返回首字母在字符串中的下标
    if(s.find('x')==string::npos){     }//如果没有找到的返回结果

    // 1. 查找一个字符串
    cout << s.find("chicken") << endl;        // 结果是:9

    // 2. 从下标为6开始找字符'i',返回找到的第一个i的下标
    cout << s.find('i',6) << endl;            // 结果是:11

    // 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标
    cout << s.rfind("chicken") << endl;       // 结果是:9

    // 4. 从字符串的末尾开始查找字符
    cout << s.rfind('i') << endl;             // 结果是:18-------因为是从末尾开始查找,所以返回第一次找到的字符

排序:sort(s.begin(),s.end())

判断字符串是否有空格:==' '

翻转:reverse(str.begin()+idx1, str.end()-idx2);

string类下的begin,end,rbegin,rend的用法:

begin
语法:iterator begin();
解释:begin()函数返回一个迭代器,指向字符串的第一个元素.

end
语法:iterator end();
解释:end()函数返回一个迭代器,指向字符串的末尾(最后一个字符的下一个位置).

rbegin
语法:const reverse_iterator rbegin();
解释:rbegin()返回一个逆向迭代器,指向字符串的最后一个字符。

rend
语法:const reverse_iterator rend();
解释:rend()函数返回一个逆向迭代器,指向字符串的开头(第一个字符的前一个位置)。

2,最大公约数:

辗转相除法:

            while(len1%len2!=0){
                int yu=len1%len2;
                len1=len2;
                len2=yu;
            }
return len2;

自带函数:

__gcd(int a,int b);

3,int与char之间的转换

// 利用ASCII码的差值,直接用char的值减去'0'或者加上'0'
char a = '1';
int b = a - '0'; // b = 1;
int c = 1;
char d = c + '0'; // d = '1';

4,vector的使用

C++ 数组(vector)常用操作总结_vector操作-CSDN博客

5,哈希表的使用与“增删改查”

unordered_map<int,int> map;

unordered_set<int> set;

增加元素:map[1]=10或者map.insert(pair<int,int>(1, 10))

(对于set:set.insert(1))

遍历方法:for(auto it:map){it.firstit.second}

                迭代器方法:for(auto it = map.begin(); it != map.end(); ++it){it->firstit->second}

查找:map.find(Key):

        没找到返回map.end();(set也是)

        找到的话返回一个迭代器:map.find()->second即可得到对应的value

计数:map.count(Key)查找哈希表中key的键值对,返回其数量,为1,则找到,若没找到则返回0

        也可用来查找是否存在某个Key

删除:map.erase(Key)(set也是)

大小:map.size()        返回键值对的个数

        map.empty()        判断是否为空,返回true/false

清除:map.clear()

补充:关于迭代器

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

6,指针p

*p:p这个指针指向的对象

p=&a:取a的地址给p

int* p=&a:定义指针p,该指针指向一个int

7,链表

写一个链表结构:

struct ListNode {
    //基础内部结构
    int val;
    ListNode *next;//一个指向ListNode的指针

    //包含的用法
    ListNode() : val(0), next(nullptr) {}//一个用法
    ListNode(int x) : val(x), next(nullptr) {}//一个用法,可以联想创建一个新的节点时的操作,创建一个给定值的节点
    ListNode(int x, ListNode *next) : val(x), next(next) {}//一个用法,创建一个给定值并且指定指向节点的新节点
};

2130. 链表最大孪生和 - 力扣(LeetCode)(快慢指针+反转链表)

链表的快慢指针技巧

(快的走两个next,慢的走1个next)(可用于判断中点,但是需要考虑节点数奇偶)

链表的荷兰国旗,如果让一个链表按照小于等于大于排,咋排呢?

遍历链表,不断构建三个部分的链表,最后首尾相连。

链表的创建节点与修改!!!!!!!!!!!

ListNode* ji=head:对ji修改就是对head修改。

克隆的写法:ListNode* cloneNode = new ListNode(node->val)

8,关于栈和队列的知识:

定义栈:stack<数据类型:可以是int、TreeNode*等>名称;

压:p.push(被压元素);

弹:p.pop();                弹出栈顶的元素

p.empty()                如果栈中元素个数为0返回true,栈不为空返回false

p.top()                返回栈顶部的元素

p.size()                返回中元素的个数

定义队列:queue<数据类型:可以是int、TreeNode*等>名称;

压:q.push(被压元素);

弹:q.pop();                弹出队列头部的元素

q.empty()                如果栈中元素个数为0返回true,栈不为空返回false

q.front()                返回队列头部的元素

q.size()                      返回队列元素的个数

.emplace()比push()更好使!!!!!!!!!!!!

堆:

大根堆表示父节点都比子节点大

小根堆表示父节点都比子节点小

heap操作的四个函数

  • make_heap( vec.begin(), vec.end(), less<int>() ):建立堆(要么大顶堆,要么小顶堆)
    • 通过对vector进行建堆操作,将原vector转换为堆,调用元素时依然可以用vec[n]
    • 大顶堆,就每一个函数都加上第三个参数less<int>(),假如元素是int类型的
      小顶堆,就每一个函数都加上第三个参数greater<int>(),假如元素是int类型的,一直加上,一直一致。
  • push_heap( ): 在堆中添加元素
    • push_heap()用于把数据插入到堆中,它也有三个参数,其意义与make_heap()的相同,第三个参数应与make_heap时的第三个参数保持一致。
    • 使用时需要注意的是:在使用push_heap()前,请确保已经把数据通过q.push_back()传入q中,而不是在push_heap()后再使用q.push_back(t)!!
    • 1:vec.push_back(12);                   2:push_heap(q.begin(), q.end(), less<int>());
  • pop_heap( ): 在堆中删除元素
    • pop_heap()用于将堆的第0个元素与最后一个元素交换位置,然后针对前n - 1个元素调用make_heap()函数,它也有三个参数,参数意义与make_heap()相同,第三个参数应与make_heap时的第三个参数保持一致。
    • 因此,需要注意:pop_heap()函数,只是交换了两个数据的位置,如果需要弹出这个数据,请记得在pop_heap()后加上:vec.pop_back();

  • sort_heap( ): 堆排序
    • sort_heap()是将堆进行排序,排序后,序列将失去堆的特性(子节点的键值总是小于或大于它的父节点)。它也具有三个参数,参数意义与make_heap()相同,第三个参数应与make_heap时的第三个参数保持一致。大顶堆sort_heap()后是一个递增序列,小顶堆是一个递减序列。

优先队列:

使用优先队列表示大小根堆:(省略第三个参数或者写成less都是大根堆(默认大值在堆顶        )。greater是小根堆。)

priority_queue<int, vector<int>, less<int>>s;//less表示按照递减(从大到小)的顺序插入元素
priority_queue<int, vector<int>, greater<int>>s;//greater表示按照递增(从小到大)的顺序插入元素

1.区别:它和queue不同的就在于我们可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队,并且没有front(),back()函数,只用top()访问队首元素
2.相同:优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的,都包含同一个头文件.

和队列基本操作相同:

  • top 访问队头元素
  • empty 队列是否为空
  • size 返回队列内元素个数
  • push 插入元素到队尾 (并排序)
  • emplace 原地构造一个元素并插入队列
  • pop 弹出队头元素
  • swap 交换内容
  •     struct cmp{ 
        bool operator ()(pair<int,int>& m,pair<int,int>& n){ 
            return m.second>n.second;//最小值优先 
            } 
        }; 
    
    priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> q;

    按照数据对中的第二个值进行排序,并且小的在前。

9,牛客网的输入输出样式:

输入:

(1)cin

注意1:cin可以连续从键盘读入数据

注意2:cin以空格、tab、换行符作为分隔符

注意3:cin从第一个非空格字符开始读取,直到遇到分隔符结束读取

(2)getline()

从cin的注意中,也可以看出,当我们要求读取的字符串中间存在空格的时候,cin会读取不全整个字符串,这个时候,可以采用getline()函数来解决。

注意1:使用getline()函数的时候,需要包含头文件<string>

注意2:getline()函数会读取一行,读取的字符串包括空格,遇到换行符结束

(3)getchar()

该函数会从缓存区中读出一个字符,经常被用于判断是否换行

输出:

cout

使用sort函数进行排序(自定义)

sort(begin, end, cmp)

begin为指向待sort()的数组的第一个元素的指针,end为指向待sort()的数组的最后一个元素的下一个位置的指针,cmp参数为排序准则,cmp参数可以不写,如果不写的话,默认从小到大进行排序。

如果我们想从大到小排序可以将cmp参数写为greater<int>()就是对int数组进行排序,当然<>中我们也可以写double、long、float等等。如果我们需要按照其他的排序准则,那么就需要我们自己定义一个bool类型的函数来传入。自行定义的例子:

static bool compareFirstElement(const std::vector<int>& a, const std::vector<int>& b) {
    return a[0] < b[0];
}
int main() {
    // 创建一个二维vector
    std::vector<std::vector<int>> twoDVector = {
        {3, 2},{1, 4},{2, 6},{5, 3}
    };

    // 按每行的第一个数进行排序
    sort(twoDVector.begin(), twoDVector.end(), compareFirstElement);
    return 0;
}

重点:写cmp子函数时,加上static!!!!!!!!!!!!!!!!!!!(要不会报错)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值