知识点积累

2018.10.25

String&字符串字面值

  • "hello,world" 字符串字面值
  • string s="hello,world" string类型
    字面值不能直接相加
    错误:string str="hello"+"world"
    正确:string str=s+"hello"+"world"
    错误:string str="hello"+world"+s
    需要保证string类型在字面值前面(左侧)

for-下标循环&迭代器循环
泛型编程
一般程序中不考虑其他元素,我们都可以写成迭代器循环
有的容器类型没有提供下标运算符,不能使用下标循环。

二维vector的初始化及运算

  • 初始化的程序步骤
  • 能否使用数组的下标 matrix[0].size()

数组及多维数组
1.数组的大小确定不变,不能随意增添数组。不知道元素的确切个数还是要使用vector
2.数组的特性:在用到数组名字的地方,编译器会自动的将其替换为一个指向数组首元素的指针。
3.c++本质上来说是没有多维数组的,所谓的多维数组只是数组的数组。
4.对于范围for语句,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型。

int cnt=0;
for(auto &row:array)
    for(auto &col:row){
        col=cnt;
        ++cnt;
    }
// 这个也可以实现
for(auto row:array)
    for(auto &col:row){
        col=cnt;
        ++cnt;
    }
// 这个就实现不了
for(auto row:array)
    for(auto col:row){
        col=cnt;
        ++cnt;
    }

初始化row的时候,会自动将这个数组形式的元素转换成指向该数组内首元素的指针。下一个内层循环就不合法了。

有效的预处理命令总是以“#”开头
(1)头文件包含#include
(2)宏定义 #define
(3)条件编译 #ifdef #endif

//统计二进制数中“1”的个数,用如下代码
int fun(int value)
{
    int cnt = 0;
    while(value)
    {
        cnt++;
        //消除所有1,变成0,用二进制的与命令
        value = value & (value - 1);
    }
}
//统计二进制数中“0”的个数,用如下代码
int fun(int value)
{
    int cnt = 0;
    while(!value)
    {
        cnt++;
        //消除所有0,变成1,用二进制的或命令
        value = value | (value + 1);
    }
}

程序中判断条件的短路
while(z-->0 && ++x<5)
当z=0的时候执行while,z>0不成立,z--后z=-1;后面的语句被短路将不再执行。

指针类型占8个字节,char一个字节,int4个字节
结构体struct的总大小sizeof一定是最大字节的整数倍。

2018.10.29

开始学习字符串的相关问题
注意区分vector<string>和其中字符的区别
string相当于一个容器,其中的每个字符是其真正的元素
每个元素vector[index]是一个字符串 string
string[index]则是一个char

2018.10.30

利用vector可以高效率简洁的实现stack
注意vector特有的push_back()和pop_back()对应“进栈”和“出栈”
其实感觉关联容器很简单啊
啪啪打脸!!!!!
关联容器
主要就是两种类型:
map
set
再根据关键字是否可以重复(multimap)
元素是否有序 (unordered_map)进行划分。
无序元素采用哈希函数来组织元素。
实现sort(.begin(),.end()) blogs自己实现功能
map就是一个关联数组 associative array
map中一个就是一个pair类型对象(first-key,second-value)
map提供下标操作 map[key] 返回value值,如果key不存在则新建一个key并将其初始化。
set关键字的简单集合,没有值value

2018.11.1

对于链表结点删除以及更改问题:
要把头结点进行复制保存,应用于返回。
复制的结点进行删除及更改的操作,这样不会影响原始的链表结点。
新建一个空的结点 ListNode node(0)
以及如何去定义结点指针
this node can't use '->next' but use '.next'

  • 链表的删除存在很大问题
  • 就是如何在修改这个结点同时保留链表的头结点,最后进行返回。这个一直不是很明白!!!

2018.10.2

逻辑logistic regression 中
梯度上升法(下降法)采用的权重更新公式的数学表达式和编程过程中的表达式之间的联系理解不是很好。或则就是没有理解这个编程表达式的具体含义

宏替换不占用程序运行时间:
宏是在预编译期间进行的,将代码中的指定字符转换,转换结束后,再进行编译,所以不占用程序运行时间

2018.10.3

vector<int> 进行(beigin(),end())返回的是一个iterator,这个迭代器该如何使用?
能否直接进行排序,按下标值选取其中的元素
std::sort() 可以直接对vector进行排序。这个算是标准库函数的调用

2018.10.4

关于链表的知识点,一个最基本的知识点一定要烂熟于心
合并两个有序链表
这个基本的知识点,可以应用于很多的程序当中子程序来实现链表的各种功能。
divide and conquer 一般与 recursion 相结合使用
注意分而治之的使用情况及条件(连续的大问题转换成小问题解决,再进行bottom-to-up 递归)
如果能用栈来解决的问题,那么递归也可以实现
递归在本质上就是一个栈结构。
但是递归容易导致调用函数栈的溢出,其代码的鲁棒性不是很好。对于一些层级很深的函数慎用递归来实现。
双向链表的要求不是很高,基本的数据结构也还是要理解记忆一下


2018.10.5

*和&的知识点

符号 * &
定义语句 定义一个变量指针 定义一个变量引用(别名)
非定义语句 取指针变量指向的内容 取这个变量的地址
专题

1.基本知识点

  • 度:树的度是树内各结点度的最大值

  • 深度(高度):结点的最大层次(level)

  • 二叉树:
    满二叉树,所有分支结点都有左子树和右子树,所有叶子结点都在同一层上面
    完全二叉树,按层序编号,如果编号为i和满二叉树编号为i的结点在同一个位置

2.二叉树的性质
这个在面试基础题中经常考查到

  • 二叉树\(i\)层上至多有\(2^{i-1}\)个结点

  • 深度为\(k\)的二叉树最多有\(2^{k}-1\)个结点

  • 对于任意一棵二叉树,终端结点个数\(n_{0}\)度为2的结点个数\(n_{2}\)\(n_{0}=n_{2}+1\)

  • 具有n个结点的完全二叉树的深度为\([log_{2}n]+1\)

  • n个结点的完全二叉树,结点按层进行编号,对于任一结点 i 结点
    如果i=1,其为根结点无双亲。如果i>1,其双亲结点为[i/2]
    如果2i>n,结点i无左孩子,否则其左孩子是结点2i
    如果2i+1>n,则结点i无右孩子;否则其右孩子结点是2i+1.

3.二叉树的遍历

三种遍历6种方法 都要非常熟悉

在树的递归中,注意如何返回 可以直接返回递归表达式。

November 6, 2018

一个无返回的函数,其修改的结果是什么类型
迭代器能否使用for循环
可以使用循环

std::vector<int> ints {1,2,4,8};
for (auto it = ints.cbegin(); it != ints.cend(); it++)
  • 函数的调用和定义都可以嵌套使用
  • malloc是函数
  • 各种运算符的优先顺序:
    赋值运算符<逻辑运算符<关系运算符<算术运算符
  • 系统函数符可以作为自定义标识符

November 7, 2018

在二叉树中函数利用递归recursion深度优先遍历DFS 的优缺点分析

recursion DFS
优点
缺点

今天见到的最漂亮的代码,可以记下来

// 实现二叉树转换成右二叉树
// 有点和树的旋转变换类似
class Solution {
public:
    void flatten(TreeNode *root) {
        TreeNode*now = root;
        while (now)
        {
            if(now->left)
            {
                //Find current node's prenode that links to current node's right subtree
                TreeNode* pre = now->left;
                while(pre->right)
                {
                    pre = pre->right;
                }
                pre->right = now->right;
                //Use current node's left subtree to replace its right subtree(original right 
                //subtree is already linked by current node's prenode
                now->right = now->left;
                now->left = NULL;
            }
            now = now->right;
        }
    }
};

fork()函数
1.fork()函数会把它所在语句以后的语句复制到一个子进程里,单独执行。
2.如果printf函数最后没有"\n",则输出缓冲区不会被立即清空,而fork函数会把输出缓冲区里的内容也都复制到子进程里。
所以,父进程和子进程各输出2个Hello,共4个。
如果第一个printf("Hello");写成printf("Hello\n");,则只会输出3个Hello,父进程2个,子进程1个。

类型 位数(bit) 字节(2字节=1字)
char 8 1
short 16 2
int 16 2
long 32 4
long long 64 8
float 32 4
double 64 8

malloc 和 new
都是从堆上分配内存
malloc 删除内存使用free
new新建的内存删除 需要使用 delete

November 8, 2018

程序运行的必要条件:
头文件的路径(utilities)这是个公用的工程文件夹 以及头文件的获取
文件路径(\path windows-vs 以及 /path -xcode)

在程序中注意,return语句和要print内容的顺序
如果print语句在return语句后运行,则print的内容无法输出--这是在解释性语言python运行结果
编译性语言有待检测

November 10, 2018

还是关于树的知识点
关于树的深度遍历的理解
深度遍历在程序中的使用!!!

November 11, 2018

下午看一看深度优先遍历
和分而治之在深度优先遍历中的应用
问题可以想明白,但是就是不会做。

November 12, 2018

C++循环的应用
for(int i=0;i<s.size();i++)
要替换为
for(auto i:s) 更加的简洁明了

树的遍历问题:知识盲区
树应该是从下面叶子结点向上根结点进行修改
怎么从下往上
这个就要实时的进行返回。

November 13, 2018

在非二叉树中,对于孩子结点集,通常是vector
需要遍历循环来讲结点集进行push_back()
和广度优先遍历结合实现非二叉树的层序遍历
两个栈来实现队列
主要是两个栈的来回pop(),push()实现队列性质
也可以用一个栈来实现,时间复杂度要高点?
构造函数(constructor):
每个类都分别定义它的对象被初始化的方式,类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数

构造函数的任务是初始化类对象的数据成员,无论何时,只要类的对象被创建,就会执行构造函数。
构造函数没有返回类型

x++只能作为右值,++x可为右值,可为左值

x++,将x自增1,返回x原来的值,这个值是一个临时值,不能向其赋值。

November 14, 2018

template
template <typename T>
模版的定义以关键字 template 开始,后面跟着一个模板参数列表 template parameter list
注意:在模版定义中,模版参数列表不能为空。
T是一个模版实参,一般编译器complier会根据调用函数实参来初始化模版实参

编译器生成改变模版实参生成的版本一般称为模版的实例 instantiation

头文件中的:
#pragma once
防止宏定义被编译器多次编译

#ifndef ...
#define ...

#endif
是一样的效果

当然也可以一起使用,先使用
# pragma once
再使用传统的 if语句来实现(这个一般用的比较多,也是程序员经常用的可以实现跨平台的使用)

一个几乎不可能用到的知识点,switch case 语句
如果case语句后面有没有break语句结束,有则跳出switch语句,没有则执行下一个case语句。

sizeof new delete 都不是函数,都是关键字keywords
类的静态成员?

November 15, 2018

模板 template:C++范型编程的基础
顾名思义,其是创建类或者函数的公式

ping: packet internet groper
英特网包探索器

November 16, 2018

malloc()函数如何分配新空间地址
当函数是一个无返回函数的时候,如果需要进行递归需要返回值的时候 return;
散列函数的实现,hashtable 是一个非常重要的数据结构。
处理hash冲突方法有:
开放定址法(线性探测法、线性补偿探测法、随机探测法),拉链法,建立公共溢出区,再散列法
稀疏矩阵压缩:

三元组表示稀疏矩阵可大大节省空间,但是当涉及到矩阵运算时,要大量移动元素。
十字链表表示法可以避免大量移动元素。

November 17, 2018

python

heapq:
heap queue algorithm =priority queue
堆列和优先队列

C++

两个知识点
一个是关联容器
当我们从map中提取一个元素的时候,我们得到的是一个pair类型的对象
pair是一个生成特性类型的模版
priority_queue 优先队列
priority_queue
explaination:A priority queue is a container adaptor that provides constant time lookup of the largest (by default) element, at the expense of logarithmic insertion and extraction.
专门是为了找到最大k个元素而实现的数据结构
其插入的元素不再队列尾部,而是根据特定的优先级排列。
也就是元素插入即排序

November 19, 2018

Include<cassert>

assert 又叫断言,假设
assert 是一个宏,不是函数,bool类型

前置条件断言:代码执行之前必须具备的特性
后置条件断言:代码执行之后必须具备的特性
前后不变断言:代码执行前后不能变化的特性

对于递归的实现,能用自底向上的方法,就用自底向上递归的方法。

指针:
char *p1="123"
指针指向常量字符串,在常量区不能对其修改
在常量区,并没有在拷贝到栈中,所以不能修改

char p[]="hello world";和char *p="hello world"的区别;前者存放在栈里,后者存放在静态区
字符串初始化数组时要记得将数组长度加1,因为字符串默认的末尾有一个‘\0’

数组作为函数参数时,当作普通指针来记

static 全局静态变量,其值作用于全局作用域

November 20, 2018

哈希表,关联容器
map,set 什么时候使用,如何使用
不是很熟悉
bucket 桶变量,不是很了解
下面这段代码包含的知识点非常多
1.哈希的元素的遍历
2.map可以进行逆序输出
3.mao的默认排序,是按第一个元素进行排序

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char,int> m;
        string result;
        map<int,vector<char>> m_freq;
        for(auto c:s){//1
            m[c]++;
        }
        for(auto x:m){
            m_freq[x.second].push_back(x.first);//3
        }
        for(auto it=m_freq.rbegin();it!=m_freq.rend();it++){ // 2 rbegin() 进行逆序输出
            // map有的操作,但是unordered_map没有
            for(auto c:it->second)// 遍历vector中所有的字符串
                result.append(it->first,c);
        }
        return result;  
    }
};

November 21, 2018

数据结构,不管什么时候能用 vector就用vector

字符串的问题,记得使用长数组来实现哈希表的功能。

遇到字符串的问题就歇菜,字符串还是需要加强

November 22, 2018

python中math.log()不能对矩阵直接操作
可以直接使用 np.log()

November 23, 2018

很重要的一个知识点:
istringstream ss;
while(ss>string)
字符串流,等同于cin

如果直接对string直接使用for(it=string.begin())这样得到的是 char

哈希表和二叉排序树的重点考察都是数据结构而不是算法

快速排序的c++代码要尽快理解
结合java版本的也写个c++版本的快排

November 24, 2018

binary search :
能使用 lo+(hi-lo)/2 就尽量使用,不要使用
(lo+hi)/2 这个很容易溢出。

找到旋转数组中最小值的下标,这个很关键。
二分查找中,lo及hi的赋值很重要
以及判断条件的选取都是关乎整体代码运行的

posted @ 2018-11-13 21:45  dengshuo7412  阅读(205)  评论(0编辑  收藏  举报