Leetcode刷题笔记01:【1】两数之和 (C/C++编译全过程 static关键字 extern关键字 vector unordered_map)

第一天 2021-3-3 每日刷两题之一

一、C/C++编译全过程

C语言编译过程详解

  1. 预处理(Preprocessing):预处理用于将所有的#include头文件以及宏定义替换成其真正的内容。test.c->test.i
    ①以.c文件为单位进行,各个.c文件之间不知道彼此的存在;
    ②将#include的.h文件代码放入对应.c文件中,此时.h文件已经完成全部作用可以废弃(帮助理解.h文件本质,就是为了减少代码的重复编写而产生的,没有特殊功能);
    ③将#define宏定义的值放入代码对应位置
    test.c->test.i

  2. 编译(Compilation):将经过预处理之后的程序转换成特定汇编代码(assembly code)的过程。test.i->test.s
    ①以.c文件为单位进行,各个.c文件之间不知道彼此的存在;
    在这里插入图片描述

  3. 汇编(Assemble):汇编过程将上一步的汇编代码转换成机器码(machine code) test.s->test.o
    ①以.c文件为单位进行,各个.c文件之间不知道彼此的存在;

  4. 链接(Linking):链接过程将多个目标文以及所需的库文件(.so等)链接成最终的可执行文件(executable file)。

二、static关键字

C/C++在头文件中使用static定义变量意味着什么
定义全局变量时/函数使用static,意味着该变量/函数的作用域只限于定义它的源文件中,其它源文件不能访问。

三、extern关键字

C/C++中extern关键字详解
extern关键字只用在变量上,代表声明一个变量而不是定义。

当在头文件中声明一个变量,必须使用static/extern,否则在将多个引用该头文件的c文件链接时,引发多重定义的错误。在这里插入图片描述static:该变量只在各个c文件中单独有效
extern:该变量由所有extern共享(此时禁止在头文件中初始化)

★为什么头文件声明函数不需要static/extern关键字?

重复定义会引发错误,重复声明并不会。
函数声明与定义变量的声明与定义是有区别的。
函数只要未写出函数体,即为声明,不需要额外加extern关键字;
变量必须加上extern关键字才能被编译器认定为一个声明;
编译器为什么不报重定义函数错误?
因此也可以得出结论,extern关键字不会用在函数上。
★★★函数声明中的extern问题

四、STL:vector

★★C++ vector的用法总结(整理)

vector<int> result={1,2,3}//可以用这种方式初始化
result.push_back(4)  //插入元素
result.emplace_back(4)//相对于push_back, 但比它更有效率

c++ vector自带的排序

vector是表示可变大小数组的序列容器。

五、STL:map&unordered_map

c++ map与unordered_map区别及使用
都负责存储key-value键值对数据

#include<map> //底层为红黑树
#include<unordered_map> //底层为哈希表

哈希表和红黑树的对比


★★C++ STL unordered_map容器用法详解(成员方法表)


可以使用如下三种方式赋值

unordered_map<string,int> hashtable
hashtable["key"]=7; 
hashtable.emplace("key",7);
hashtable.insert({"key",7});//使用insert需要先组合参数!

unordered_map常用查找结构
unordered_map<int, int> hashtable;
for (int i = 0; i < n; ++i) {
    auto it = hashtable.find(n); //查找key=n,未找到则返回一个指向容器中最后一个键值对之后位置的迭代器
    if (it != hashtable.end()) {
        return "find";
    }
    return "not find";
}

// 使用count()代码更简洁,若存在返回1,不存在返回0
unordered_map<int, int> hashtable;
for (int i = 0; i < n; ++i) {
    if (hashtable.count(n)) {
        return "find";
    }
    return "not find";
}

// 如何使用查找到的返回值
// hashtable将返回一个迭代器,使用如下方法取出key和value
itr=hashtable.find(n);
itr->first; //返回key值
itr->seconde; //返回value值
unordered_map常用遍历结构
unordered_map<int,int> h;
for(auto iter=h.begin();iter!=h.end();iter++){
	cout<<iter->second;
	cout<<h[iter->first];
}

成员方法功能
begin()返回指向容器中第一个键值对的正向迭代器。
end()返回指向容器中最后一个键值对之后位置的正向迭代器。
cbegin()和 begin() 功能相同,只不过在其基础上增加了 const 属性,即该方法返回的迭代器不能用于修改容器内存储的键值对。
cend()和 end() 功能相同,只不过在其基础上,增加了 const 属性,即该方法返回的迭代器不能用于修改容器内存储的键值对。
empty()若容器为空,则返回 true;否则 false。
size()返回当前容器中存有键值对的个数。
max_size()返回容器所能容纳键值对的最大个数,不同的操作系统,其返回值亦不相同。
operator[key]该模板类中重载了 [] 运算符,其功能是可以向访问数组中元素那样,只要给定某个键值对的键 key,就可以获取该键对应的值。注意,如果当前容器中没有以 key 为键的键值对,则其会使用该键向当前容器中插入一个新键值对。
at(key)返回容器中存储的键 key 对应的值,如果 key 不存在,则会抛出 out_of_range 异常。
find(key)查找以 key 为键的键值对,如果找到,则返回一个指向该键值对的正向迭代器;反之,则返回一个指向容器中最后一个键值对之后位置的迭代器(如果 end() 方法返回的迭代器)。
count(key)在容器中查找以 key 键的键值对的个数。只会返回0或1
equal_range(key)返回一个 pair 对象,其包含 2 个迭代器,用于表明当前容器中键为 key 的键值对所在的范围。
emplace()向容器中添加新键值对,效率比 insert() 方法高。
emplace_hint()向容器中添加新键值对,效率比 insert() 方法高。
insert()向容器中添加新键值对。
erase()删除指定键值对。
clear()清空容器,即删除容器中存储的所有键值对。
swap()交换 2 个 unordered_map 容器存储的键值对,前提是必须保证这 2 个容器的类型完全相等。
bucket_count()返回当前容器底层存储键值对时,使用桶(一个线性链表代表一个桶)的数量。
max_bucket_count()返回当前系统中,unordered_map 容器底层最多可以使用多少桶。
bucket_size(n)返回第 n 个桶中存储键值对的数量。
bucket(key)返回以 key 为键的键值对所在桶的编号。
load_factor()返回 unordered_map 容器中当前的负载因子。负载因子,指的是的当前容器中存储键值对的数量(size())和使用桶数(bucket_count())的比值,即 load_factor() = size() / bucket_count()。
max_load_factor()返回或者设置当前 unordered_map 容器的负载因子。
rehash(n)将当前容器底层使用桶的数量设置为 n。
reserve()将存储桶的数量(也就是 bucket_count() 方法的返回值)设置为至少容纳count个元(不超过最大负载因子)所需的数量,并重新整理容器。
hash_function()返回当前容器使用的哈希函数对象。

当向unordered_map插入重复的key值时,将直接失败。

六、【题】两数之和

使用哈希表(cheat?)存储已经扫描过的数字,再次用到时很快的找到有没有符合要求的数字。

相比枚举法:
时间复杂度由O(N^2)降低为O(N)
空间复杂度由O(1)升为O(N)

借着哈希算法的无敌强行降低,牛!

七、Iterator

C++迭代器实现原理(附带了Java)
★★ C++迭代器(STL迭代器)iterator详解

vector::iterator i; //定义正向迭代器

"::"的作用:

因为iterator是定义在vector的内部类,所以需要使用::来引用
java用. cpp用::

class A{
    class B{...}
    ..
}
A::B //cpp
A.B //java
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值