字符数组
前方高能char a[4]={'a','b','c','d'};
cout<<a<<endl;
这将输出什么呢,是abcd,实际上是abcdPpB
这就有点神奇
字符数组char +标识符+[],注意字符数组的最后一定会有’\0’,
例如char[]="abcd",这就是一个合法的赋值,但是char[4]="abcd"是不合法的因为带双引号的为字符串,赋值给字符数组时编译器会自动加上'\0'这时需要5个空间
原因因为本来是要加上’\0’的,但是这时位子不够了,编译器只好帮它扩扩容,也就是说这是字符数组(其实现在已经不是字符数组了)长度已经不是4了,编译器会为后面几个位子附上值(不是随机的,我也有点不清楚,这样解释先),因此后面会多输出一些。但是如果开始就把长度设为5,这时’\0’就有位子放了,也就不会多出后面那些奇奇怪怪的字符
字符串之hash算法
hash基础概念但在工程实践中,要查找的关键字往往都不是自然数,即使是自然数也有可能是很大的值。因此,只要我们提前把关键字转换为在固定较小范围内的自然数,就可以实现常数时间的查找。那么问题来了,如何实现该转换关系呢?这就是哈希函数所要完成的工作。
哈希函数:又称散列函数,是把一段有限二进制串(字符串,整数等)转换为自然数的一种函数。
哈希值:哈希函数输出的最终结果。
字符串哈希函数:输入是字符串的哈希函数。
注:实际上就是用一个函数将字符串转化为整数,然后尽可能使一个整数对应一个字符串
现在的哈希函数基本上都是满射,多个字符串会对应一个数字,这种情况佳作冲突,为了减小冲突,列举几种方法
这种方法就是用进制转换的观念,一般用128,但这样十分容易超int型的范围,因此要想办法减小范围,可以用一个较大的数去摸,这时又出现了冲突的问题,那可以用两个数同时去摸,这样用两个数表示一个字符串冲突的几率便大大降低
BKDRHash算法// BKDR Hash Functionunsigned int BKDRHash(char *str){ unsigned int seed = 1 ...
字符串之KMP算法
由(扯)来(蛋)Knuth-Morris-Pratt 字符串查找算法,简称为 “KMP 算法”,常用于在一个文本串 S 内查找一个模式串 P 的出现位置,这个算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人于 1977 年联合发表,故取这三人的姓氏命名此算法。
最长前缀和与后缀和例如给出一个字符串ABCDABD前缀和就是从前往后数i个,后缀和是从第n-i个数到最后一个,首先我们便要找到每一个字母的最长相同前缀后缀和,然后求next数组,注意,只有一个元素时是不计算前缀后缀的,直接看为0
next数组next数组考虑的是除当前字符外的最长相同前缀后缀,实际上就是前一个前缀后缀和,因为把最后一个字母上去之后必定会使后缀和少一个,因此前缀后缀和也会-1,注意next数组中会出现-1,实际上这个数组就是将原数组整体右移一位,然后在第0位补上-1
用next数组进行匹配匹配失配,j = next [j],模式串向右移动的位数为:j - next[j]。换言之,当模式串的后缀 pj-k pj-k+1, …, pj-1 跟文本串 si-k si- ...
字符形式 的数据
首先要知道asc11码
形式: db ‘…’
无论多少个单词都只需要单引号
例 db‘unix’
在代码段中使用栈
实际上栈是我们人为定义的一段内存空间,所以先要用dw来申请
dw 0,0,0,0,0,0 //申请6个字的内存空间,栈是由高内存地址到低内存地址,所以栈顶为cs:Chstart: mov ss,csmov ss,axmov sp,Ch
ss,sp就是前面所说的栈的指针
在不更改注册表的情况下把程序移出c盘
这里用的类似于快捷方式。用mklink命令,这个命令可以将两个文件夹连接,一个是真实存放内容的文件夹,另一个只有名称,实际内容并不放在哪里。所以我们可以创建一个这样的文件夹来骗过程序。例如 office
首先要用cmd而不能用powershell,这是系统自带命令.然后在其他盘建一个同名的文件夹。注意c盘的文件夹不要创建,执行命令后系统自动创建。
mklink /J "C:\Program Files (x86)\Microsoft Files" "D:\Program Files (x86)\Microsoft Files"
压缩矩阵
对于特殊的矩阵,例如上下三角矩阵,对称矩阵,三对角矩阵,可以转化成1维矩阵,减小空间的消耗。
特殊矩阵对称矩阵对称矩阵有 aij=aji的特性,因此可以只保存一边,也就是压缩成 n(n+1)/2个
如果我们用一个一维数组s[n(n+1)/2]来保存,那么它域原矩阵的对应关系k= i(i-1)/2+j-1 i>=j j(j-1)/2+i-1 i<j
这个式子先只考虑一边,先看i>=j的情况。此时第一行中压缩矩阵只保存一个值,第二行两个值,依此类推。所以对于第i行先把前i-1行中对应压缩矩阵的值的数量加起来,也就死i(i-1)/2,之后再加上第j行的第j-1个(这里因为数组下标是从0开始)。
这个例子中的行数是从第一行开始,实际上应该从第0行开始,所以k= i(i+1)/2+j i>=j j(j+1)/2+i i<j举个例子,第0行第0个在k中对应位置就是0
上下三角矩阵对称矩阵行数和列数相同
上三角矩阵其实就是对称矩阵中 i>=j的那一段
下三角矩阵中第一行的压缩矩阵元素数量是n,第二行是n-1,以此类推,我们也可以得到相应的关系式k=(2* ...
合法的字符常量
用英文单引号括起来的一个字符,例如’a’,’ ‘等等。空格也是一个字符常量
注意 1.转义字符也属于字符常量,例如’\t’,’\n’等,但是’\97’不算
双端队列deque
普通的队列有许多限制,例如从一边删除插入,不能使用迭代器(因为空间不连续)等等。双端队列就允许从两边插入
deque的特点:
1、支持随机访问,即支持[]以及at(),但是性能没有vector好。
2、可以在内部进行插入和删除操作,但性能不及list。
deque和vector的不同之处:
1、两端都能够快速插入和删除元素。vector只能在尾端进行。
2、deque的元素存取和迭代器操作会稍微慢一些。因为deque的内部结构会多一个间接过程。
3、迭代器是特殊的智能指针,而不是一般指针。它需要在不同的区块之间跳转。
4、deque可以包含更多的元素,其max_size可能更大。因为不止使用一块内存。
5、不支持对容量和内存分配时机的控制。
注意:在除了首尾两端的其他地方插入和删除元素,都将会导致指向deque元素的任何pointers、references、iterators失效。不过,deque的内存重分配优于vector。因为其内部结构显示不需要复制所有元素。
迭代器属于随机存取迭代器。
以上都是复制粘贴的,从以上我们可以看出它与vector相似,不同在于它可以从两头插入,这样插 ...
单调队列
也就是有一个数列a,要求你求数列b和c,b[i]是a[i]…a[i+w-1]中的最小值,c[i]是最大值。如果a是1,3,-1,-3,5,3,6,7,则b为-1,-3,-3,-3,3,3,c为3,3,5,5,6,7。
这个问题相当于一个数据流(数列a)在不断地到来,而数据是不断过期的,相当于我们只能保存有限的数据(sliding window中的数据,此题中就是窗口的宽度w),对于到来的查询(此题中查询是每时刻都有的),我们要返回当前滑动窗口中的最大值\最小值。注意,元素是不断过期的。
解决这个问题可以使用一种叫做单调队列的数据结构,它维护这样一种队列:
a)从队头到队尾,元素在我们所关注的指标下是递减的(严格递减,而不是非递增),比如查询如果每次问的是窗口内的最小值,那么队列中元素从左至右就应该递增,如果每次问的是窗口内的最大值,则应该递减,依此类推。这是为了保证每次查询只需要取队头元素。
b)从队头到队尾,元素对应的时刻(此题中是该元素在数列a中的下标)是递增的,但不要求连续,这是为了保证最左面的元素总是最先过期,且每当有新元素来临的时候一定是插入队尾。
满足以上两点的队列就是单调 ...