这篇文章并不是讲UE4的内容,而是聊下关于算法和C++的一些有意思的地方,没有C++基础的也是可以来看看因为本文将不会出现代码而且说不定有些地方可以帮你打开新大陆。
既然是闲聊,那就来说点给我带来印象最深刻的一些东西吧,这边推荐看一本叫《编程之美》的书,在这本书里有个我印象最深刻的一个例子,题目的原意是要求在一个8byte的变量里保存2个3×3的位置信息,这个我虽然第一反应就是位运算来解决这个问题,因为一个8byte的类型可以分成前4btye和后4btye来看待因为一个变量无法直接访问前半段和后半段,这个如果了解过CPU寄存器的应该会很了解,因为CPU的寄存器如AX(16位,2byte)就是可以分成AH(8位,1byte)和AL(同AH),现在我们来看看,4byte也就是有2的4次方个可能即16个数,而3×3的位置信息只有9个数,所有肯定可以存储全部信息。
那么我再讲下位运算,首先要知道数据在内存中是以2进制的方式来放置的,也就是0001100这样的,既然是2进制的也就是说任何数据都是可以进行运算的包括加减乘除和逻辑运算,而位运算就是逻辑运算的一种,还记得高中数学学过的“或与非”嘛,比如:是或否就是否,那么现在我们把这个”是”看成1,”否”看成0,那么这样就可以把2进制的内容看成一串逻辑判断了(这边说的不严谨因为要减低难度);
然后我们再来了解下位移操作,位移分为左位移和右位移,这里为了简单解释就不讨论有符号数的位移方式了。位移操作的用途是为了减少CPU进行计算的开支,CPU在运算的时候乘法和除法是最占用CPU资源的计算,那么如果我要计算一个2×2的结果的话可以使用左移操作,2的2进制是0010,按二进制形式把所有数字向左移动相应的位数,高位移出(舍弃),低位的空位补0。相当于乘以2的n次方,那么相应的右移就是除法,按二进制形式把所有数字向右移动相应的位数,低位移出(舍弃),高位的空位补0。相当于除以2的n次方。不过,位移一样可以用于位运算,可以将前面或者后面的内容移动到其他位置,比如这样操作:0011左移1位就是0110,这样就相当于将某个有效内容移动到了前面一位。
现在,我们回头看看题目,那就可以这样操作:先将这个8byte的变量”异或”自己来清空空间,然后使用”或”操作来加入数据,比如这样: 0000 or 0011就是变成了0011相当于就是存储了数据进去,然后使用位移操作将现在输入的数据移动到最前面,比如:00000011 << 6就变成了11000000,这样就可以与之前保存的内容进行”或操作”来保存数据了。
那么为什么说这个题目是我印象最深刻的呢?那就是我看到另一个解决办法,既然是一个8byte的变量,为什么不使用2个4byte的变量结构体作为1个8byte的变量呢?也就是说可以像CPU使用寄存器一样使用这个8byte的变量也就是直接访问前4byte和后4byte,这样的话不就是可以大幅度减少位移操作了嘛。
//结果还是想给下代码
struct{
unsigned char a:4;
unsigned char b:4;
} i;
for(i.a = 1; i.a <= 9; i.a++){
for(i.b = 1; i.b <= 9; i.b++);
}
还有一个题目是将怎么在1W个服务器中快速找到坏掉的1个服务器,这1W个服务器都有1个对应的服务器存储单独的ID,也就是说如果1个服务器坏了这个ID只会出现一次,那么怎么快速的找到这个坏的服务器;
这个问题首先要排除掉多重遍历寻找,使用多重遍历寻找的话时间成本和内存成本会非常高,在实际的使用中也是尽量少的使用,那么我们可以这样想,每个ID是单独的,那么我们就可以用哈希表来解决这个问题,因为每个键都是单独的,所以可以先遍历前1W个服务器作为哈希表,然后后1W个服务器作为键来去读取哈希表,这样的话如果有重复的话可以删除掉这个键对应的值,剩下的那个ID就是坏掉的服务器ID了,这样就可以使用2次遍历就完成了任务。
那么今天就先到这里吧,这打字打得手痛.