ov智商捉急
ov智商捉急


  • 首页

  • 关于

  • 归档

  • 标签

  • 有料

  • 一影一图

  • 装逼

  • 搜索

沙扬娜拉

发表于 2017-04-21   |  

哎我萨该彻底重建了吧。白白明年见

.me域名到期 穷狗续费无力。继续一年一换的风格转战mimimomo.asia 看起来高大上

该和学校说再见了。认真对待好下面这写日子吧。这个季节少了很多烟酒茶或许真的是老了

机器学习要点检索--基于图解机器学习

发表于 2017-02-27   |  

这是一个机器学习知识记录贴,主要内容是Ng的ML课、《图解机器学习》、《机器学习》周志华版。懒癌发作了可能就不更了

阅读全文 »

UEFI双系统小记

发表于 2017-02-20   |  

喷血了。一个小误会居然装了一个晚上。作为一个6年前就装过双系统的薛薇有些池乳。

阅读全文 »

2016回想

发表于 2017-01-18   |  

说说去年的成长

很忙,也很空虚。做着重复的事情,去了没有效率和收获的地方,跑了好几个空场。但,不得不的是,活在当下吧。暂且算是找了个工作,听大家的,先就业后择业。大家的待遇都比我好,也都比我顺利,事实上也总是如此,不是一下子就这么惨的。使劲的,假装的,学了很多,的确是很多->机器学习,计算机网络,深度学习,计算机视觉……一股脑没来由的全塞过来,倒是样样没天赋的样子。笔记做了好几本,学过的没学过的,记得快,忘得快。

晚睡,要改。旷班,要改。拿啥,要改。语塞,要改。作,要改。

少去了很多次电影院(尽管很多时候更愿意一个人。)更多spare time选择自己自己一个人撸剧撸书;很多没意思的游戏坚持了下来,又探索了一直以来倔强抗拒的moba;也更能花了。努力培养自己的消费习惯,从消费粮食到消费内容,义无反顾的加入中国特色的社会主义文化建设。文章其实很早就有了头绪,但是苦于时间实在是挤不出,囿于有些便利条件,交差的很晚,索性是在有限的条件下,写的比较丰满。

少喝了很多酒,多吃了很多饭。一直想找个平台分享吃的,可惜没找到。支付宝算半个,可惜人太丰富人格滤镜少了些。葫芦已让我有些神经衰弱,算半个逃避的借口。拿啥算另外半个。

人格改变了很多,习性却没啥改进。懒惰,拖延,矫情,自负,不解风情……好友仍是那两三个,交际没有拓展,找不到合适的圈子和兴趣,无所事事却又忙的昏天暗地。不知道是什么情况,很久没有联系的小伙伴今年都找了我,猪,ex,开火车的少年,农行狗,交大大神,成都智障儿童。。都能相互关心相互唏嘘,很好。加了很多群,没几个能说的上话。游戏玩了好几个,最喜欢的还是五六年前喜欢的。书买了好几本,最喜欢的还是翻来覆去的时间拣屎。终归也是坚持了一些事情,坚持了特别久,记账和对账,备份分类照片,更新影评和书评。

学生时代要结束了,科研的生涯也到了尽头。该不该出国,该不该找女票,该不该往技术方向发展,只能慢慢走了。自己的确是个不会做计划,不会组织的人。即便写下豪情万丈的计划,不出一周就要磨灭。总说计划赶不上变化,任何app都救不了。该学习的还有很多,期待一下吧,希望不是个坐吃等死的工作,我还是喜欢激情燃烧的。没人和我去深圳,新的环境新的人,总该收敛一些好,毕竟社会太复杂。

还有,该健身了。
还有,该旅游了。
还有,该学习英语和会计了

花钱

明明没赚多少,也没涨工资,却花的越来越大手笔了。去年都不敢奢望吃15块以上的外面现在随便一点就上30了。。吃了更多的馆子。上半年是风格和温泉。下半年是小组。但逃不了的是各种鱼和肉。放弃了坚持了很久的跑步和健身,却没胖起来,这让人失望。花了更多的钱去买零食和小吃,门口的小摊的铁板烧,自助机的酸奶,奥金星的咖啡都是常年必备。不得不说微信和支付宝的推广和运营深得我心,撺掇着我去努力消费努力赚优惠和代金券。

办了3张信用卡。浦发还多办了张我萨的。决定分门别类以后消费都使用不同的渠道了。光大主吃。

Learn Sth. the Other Day

发表于 2016-08-18   |  

近期忙着撸工作。边学边总结。

阅读全文 »

Git的小tips

发表于 2016-06-14   |  

Git是当下最流行最舒适的版本控制系统。这里大致把git容易忘记的事情做小结。

阅读全文 »

位运算各种

发表于 2016-05-12   |   分类于 代码狗 , 学习log   |  

最近发现位运算在很多场合有很多运用啊。大概有以下几个方面:

  • 涉及二进制及其2^n进制的运算
  • 很少字段的struct class的改写例如棋盘记录和模式比较
  • 逼格&效率比较高的小心机

几个运算符

符号 名称 含义
^ 按位亦或 同为0,异为1
$\mid $ 按位或 有1则1,双0为0
& 按位与 有0则0,双为1
~ 按位取反 变1为0,变0为1(包含符号位)
<< 按位左移(包括符号) 二进制每移一位乘二,最右补零
>> 按位右移(包括符号) 二进制每移一位除二,无符号最左补零,有符号补符号位
`>>> 按位无符号右移 对应二进制全指定的位数

以上均是按位操作,要区分逻辑运算&& ||和位运算符& |

关于取反

普通的Integer char等按位操作都是直接按照它们的二进制补码操作,int直接使用该数字的补码,char则先按照ascii转换成二进制在进行操作。
e.g.char a = 'a'a的ascii码十进制为097,二进制原码为1100001,这里注意,作为char,它在java中是一个无符号16位的整数,所以补齐它的
二进制原码 补码 反码(非负数原码 补码 反码相同)

000000000 1100001

取反后的补码

111111111 0011110

取反后的反码

111111111 0011101

取反后的源码

100000000 1100010

十进制即为 -98。
同理的,byte如果存储字符型也是按照先转成ascii码进行操作,即便是字符型的数字也一样。

byte a = 2;
int b = ~a;//输出b为-3
byte c = '2';
int d = ~c;//输出d为-51 2的ascii为50(十进制) 32(十六进制)

关于亦或

亦或相当的特别同时阴森啊,有几个性质

  • a^a = 0 也就是亦或自己为0,因为每位都是相同的。
  • a^a^a = a^0 = 0^a = a
  • a^b = b^a 符合交换律
  • (a^b)^c = a^(b^c) 符合结合律
  • e = a^b^c^d <-> e^a = b^c^d <-> e^a^b= c^d <-> e^a^b^c=d

既然满足交换律结合律,则如果出现这么一种情况,

[一个数组里除了一个数值出现一次,其他都出现了两次。找出这个数值。]
将这个数组全部亦或一遍,则出现两次的都可以按照交换律结合律化为0,

数组内只存在两个奇数次出现的数,其他都出现了偶数次,找出这两个数

思路:这就是上面实例的改进,因为知道了其他数字都出现了偶数次,全体亦或的结果就是x=a^b 其中a b分别是所要找的这两个数。由于a b不同,则x必然不为零,也必然存在为1的位(可以取从右第一次出现1的位置)。同时由于是亦或操作,这个1必然是a和b相异造成的。这样,把这一位为1的分一组,这一位为0的分一组,出现偶数次的依然会被分到一组通过亦或自己消除。

    //从右寻找补码中1第一次出现的位置
    public static int getFirst1(int num){
        int index = 0;
        while(index<32){//Integer有32位
            if(((num&(1<<index))^(1<<index))==0)
                return index+1;
            else
                index++;
        }
        return -1;
    }

    //判断这个数这一位是否为1
    public static boolean is1AtPos(int num,int pos){    
        return ((num>>(pos-1))&1)==1;
    }

    //寻找这两个数
    public static int[] get2Num(int[] a){
        int [] find2Num = new int[2];
        //默认初始化0
        int rs = 0;
        for (int i : a) {
            rs ^= i;//亦或全体求x
        int pos=getFirst1(rs);//寻找第一个出现1的位
        for (int j : a) {
            if(is1AtPos(j,pos))//按这位是否位1分组
                find2Num[0] ^= j;
            else
                find2Num[1] ^= j;           
        }
        System.out.println(find2Num[0]+" "+find2Num[1]);
        return find2Num;
    }

使用位亦或^节约空间的数据交换

原理:a亦或b=c,b亦或a=c,也就是亦或满足交换律;位亦或的逆运算,也就是(a^b)^b=a等于它自己。所以,只需三个亦或运算即可交换数据。看代码。

    a ^= b;
    b ^= a;
    a ^= b;

使用亦或加密

中文配合亦或加密再加上其他的一些加密算法可以很好的掩护原文。

        char  a1='晚' ,  a2='上' ,  a3='来' ,  a4='我',  a5='家' ; 
        char secret='8' ; 
        a1=(char) (a1^secret); 
        a2=(char) (a2^secret); 
        a3=(char) (a3^secret); 
        a4=(char) (a4^secret); 
        a5=(char) (a5^secret); 
        System.out.println("密文:"+a1+a2+a3+a4+a5); 
        a1=(char) (a1^secret); 
        a2=(char) (a2^secret); 
        a3=(char) (a3^secret); 
        a4=(char) (a4^secret); 
        a5=(char) (a5^secret); 
        System.out.println("原文:"+a1+a2+a3+a4+a5);

亦或判别IP地址是否相等

使用亦或在加上按位与的方式比==加&&的方式效率高。

    static int ipv6_addr_equal(int[] in6_addr_a1, int[] in6_addr_a2)
    {
    return (((in6_addr_a1[0] ^ in6_addr_a2[0]) |
        (in6_addr_a1[1] ^ in6_addr_a2[1]) |
        (in6_addr_a1[2] ^ in6_addr_a2[2]) |
        (in6_addr_a1[3] ^ in6_addr_a2[3])) == 0);
    }

关于按位与

按位与操作一般是与1配合 判断奇偶,或者判断某位是否为1;或保留下某位位数字(与位移结合)

a&1 == 0    偶数
a&1 == 1    奇数

关于按位与

按位或操作一般与0配合

按位左右移

左右移本质上就是以bit为单元进行二进制的操作,而二进制左右移n位在十进制就意味着乘以2^n或除以2^n.按位操作可以大大提升效率
港真,很多面试都有求幂的题目。很棒,刷题狗就喜欢做这种题,然而第一次碰到这题我懵逼的采用了树。傻缺了。

将二进制数绕圈循环,取往左(右)第k个为头。很多题目里面有啊

int a = a<<k | a >> (Integer.SIZE-k); //左数第k个当头
int b = b>>k | b >> (Integer.SIZE-k); //右数第k个当头

第k位置1

    a|(1<<k);

第k位置0

    a&(~(1<<k));

取第k位的数值

    a>>k&1;

后k位为0,其余为1

    (~0)&(1<<(k+1));

后k位为1,其余为0

    ~((~0)<<k);

左右移应用-二分求幂

Caution!这个思想很重要!

思路:求a^b,如果b是一个2的整数幂,举个栗子,32,那可以进行这样的迭代,由于$32=2^5$,那么就可以这样求,

  1. 第一次求 $a_1=a^2$
  2. 第二次求 $a_2=a^4=a^{2*2}={a_1}^2$
  3. 第三次求 $a_3=a^8=a^{4*2}={a_2}^2$
  4. 第四次求 $a_4=a^{16}=a^{8*2}={a_3}^2$
  5. 第五次求 $a_5=a^{32}=a^{16*2}={a_4}^2$

如果是通过迭代幂的次数,需要32次才能达到,然而通过分治的方式,只需要5次就能解算32次幂。那如果不是2的整数幂次方呢,很好办,通过将该整数分解成各个2的整数次幂的和,例如求取a的23次方,又$23=16+4+2=1$,所以原式可化为$a^{2^4+2^2+2^1+2^0}$,通过二分的方式,变形为$$(a^{16})\cdot (a^4)\cdot (a^1)\cdot (a^0)$$.
显然!上式就是二进制和十进制转换的过程,通过4+2+1=7次计算就可解出,而非单循环的23次。
其实,解算a的16次方中,即可用到$${a^4}^{2^2}$$,即计算a^的16次方只需用到2步,总共2+2+1=5次迭代就可计算完毕。
因而解决a^b次幂的步骤是

  • 将幂次化为2进制
  • 从低位遍历,为1则乘以当前幂次,为0则计算当前幂次,然后跳过,直接移至下一位
  • 当幂指数的二进制推到最高位
    public static long Power(int a, int n){
        long ans = 1;
        System.out.println("幂指数二进制:"+Integer.toBinaryString(n));
        while (n > 0) {
            if ((n & 1)!=0) {//末位不为零
                ans *= a;
            } 
            a *= a;//计算当前幂次
            n >>= 1;//迭代每次推一位
        }
        return ans;
    }

递归版本可能更清晰

    public static int power(int a,int n)  {  
        if(n==1) return a;  
        if(n&1)  
          return power(a,n-1) * a;  
        else  
        {  
            int t=power(a,n>>1);  
            return t*t;  
        }  
    }

下面还有更炸裂的

利用位移求二进制里1的奇偶

一般的思路就是,一位一位截末位,为1则亦或一下,为0则不管。对于Integer需要循环32次,对byte需要循环8次。

1数量为奇则返回1,为偶数则返回0。

    public static int get11Count(int x){
            int i=0;
            for(int j =0 ;j<32;j++){
                if((x&1)==1)
                    i ^= x&1;  
                x >>= 1;
            }
            return i;
    }

但四,这个方式没有体现位移的优越性。通过分治的思想,由于结果只求1或0,那么通过1位表达2位的信息,通过2位表达4位的信息,通过4位表达8位的信息,通过8位表达16位的信息,通过16位表达32位的信息。通过五次表达,就可以求出结果。
最关心的,其实只是最后一位

先看代码

    public static int get1Count(int x){
    //返回二进制数有偶数还是奇数个1 偶数返回0 奇数返回1
            x = x ^ (x >> 1);
            x = x ^ (x >> 2);
            x = x ^ (x >> 4);
            x = x ^ (x >> 8);
            x = x ^ (x >> 16);
        return x&1;
    }

解析一下。先拿byte举个栗子。因为byte是1个字节8个bit,所以表达-128~127即$-2^7\sim 2^7$.按照上面的方式,只需右移三次.举个例子88,二进制为$2^6+2^4+2^3=1011000$

第一次

        01011000
        00101100
    xor --------
        01110100  ->这个是结果!

结果的数值含义是,将原式中,这一位i与该位的上一位(即第i+1位)做了一次亦或,结果式中每出现一个1,则代表原式中必然邻位相异。其实,由于最终结果只需要表述奇偶,因此两个1为0,等同于抵消的含义。

第二次亦或

        01110100
        00011101
    xor --------
        01101001 —>第二次的结果

结果的含义是,每一个数字1表示##原式##中,每一位与其前3位二进制数值中1的个数为奇数;每一个数字0表示##原式##中,每一位与其前3位二进制数值中1的个数为0.

第三次亦或


        01101001
        00000110
    xor --------
        01101111 ->第三次结果

显而易见,每个1的出现表示与其前7个数字1出现奇数次。
最后取最后一位x&1,得到1,即原式中有奇数次1.结果正确。

进阶-计算二进制1的个数

最原始的方式

    int BitCount(unsigned int n)
    {
        unsigned int c =0 ; // 计数器
        while (n >0)
        {
            if((n &1) ==1) // 当前位是1
                ++c ; // 计数器加1
            n >>=1 ; // 移位
        }
        return c ;
    }

原始方式的改进

    int BitCount1(unsigned int n)
    {
        unsigned int c =0 ; // 计数器
        for (c =0; n; n >>=1) // 循环移位
            c += n &1 ; // 如果当前位是1,则计数器加1
        return c ;
    }

亦或清1法

int BitCount2(unsigned int n)
{
    unsigned int c =0 ;
    for (c =0; n; ++c)
    {
        n &= (n -1) ; // 清除最低位的1
    }
    return c ;
}

查表法1:

int BitCount3(unsigned int n) 
{ 
    // 建表
    unsigned char BitsSetTable256[256] = {0} ; 

    // 初始化表 
    for (int i =0; i <256; i++) 
    { 
        BitsSetTable256[i] = (i &1) + BitsSetTable256[i /2]; 
    } 

    unsigned int c =0 ; 

    // 查表
    unsigned char* p = (unsigned char*) &n ; 

    c = BitsSetTable256[p[0]] + 
        BitsSetTable256[p[1]] + 
        BitsSetTable256[p[2]] + 
        BitsSetTable256[p[3]]; 

    return c ; 
}

查表法2:4bit查表

int BitCount4(unsigned int n)
{
    unsigned int table[16] = 
    {
        0, 1, 1, 2, 
        1, 2, 2, 3, 
        1, 2, 2, 3, 
        2, 3, 3, 4
    } ;

    unsigned int count =0 ;
    while (n)
    {
        count += table[n &0xf] ;
        n >>=4 ;
    }
    return count ;
}

查表法3:8bit查表

int BitCount7(unsigned int n)
{ 
    unsigned int table[256] = 
    { 
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, 
    }; 

    return table[n &0xff] +
        table[(n >>8) &0xff] +
        table[(n >>16) &0xff] +
        table[(n >>24) &0xff] ;
}

###炸裂的平行算法
邻位相加,重复这一过程,直到只剩一位。

    #include <stdio.h>
    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[]) {
        int x;
        while (cin >> x) {
            x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
            x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
            x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
            x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
            x = (x & 0x0000FFFF) + ((x >> 16) & 0x0000FFFF);
            cout << x << endl;
        }
        return 0;
    }

###终极大招

int BitCount5(unsigned int n) 
{
    unsigned int tmp = n - ((n >>1) &033333333333) - ((n >>2) &011111111111);
    return ((tmp + (tmp >>3)) &030707070707) %63;
}

补充:位标志法

struct _byte 
{ 
    unsigned a:1; 
    unsigned b:1; 
    unsigned c:1; 
    unsigned d:1; 
    unsigned e:1; 
    unsigned f:1; 
    unsigned g:1; 
    unsigned h:1; 
}; 

long get_bit_count( unsigned char b ) 
{
    struct _byte *by = (struct _byte*)&b; 
    return (by->a+by->b+by->c+by->d+by->e+by->f+by->g+by->h); 
}

求二进制最高位前0的个数

int nlz(unsigned x)
{
   int n;

   if (x == 0) return(32);
   n = 1;
   if ((x >> 16) == 0) {n += 16; x <<= 16;}
   if ((x >> 24) == 0) {n += 8; x <<= 8;}
   if ((x >> 28) == 0) {n += 4; x <<= 4;}
   if ((x >> 30) == 0) {n += 2; x <<= 2;}
   n = n - (x >> 31);
   return n;
}

二进制逆序

int change(int x)
{
    x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
    x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
    x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
    x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
    x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
    return x;
}

位移求绝对值

x xor (not (x shr 31) + 1) + x shr 31
x = x ^ ((~(x>>31))+1) + x>>31;

交换二进制高16位和低16位

int change(int x)
{
   return (x >> 16) | (x << 16);
   //byte可写成(x >> 4) | (x << 4);
}

参考链接:

  1. https://www.lijinma.com/blog/2014/05/29/amazing-xor/
  2. http://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html

jQuery的三个坑

发表于 2016-05-10   |   分类于 代码狗 , 学习log   |  

许久没用jquery,今天碰到三个坑。小记一下

阅读全文 »

树系列码集合[持更20160517]

发表于 2016-05-03   |   分类于 代码狗 , 学习log   |  

本文持更树操作集合-码狗学习中

阅读全文 »

Svm初探

发表于 2016-04-28   |  

待更……

Effective Java 笔记--创建对象的几个Tips

发表于 2016-04-27   |  

第一章-创建和销毁对象 的一些 小tips

阅读全文 »

Hexo多客户端写作

发表于 2016-04-27   |  

Hexo是很棒的静态博客,简单的安装配置即可专注写作。
但是强迫症就是很爱折腾。倘若:

  • 主机烧了数据备份怎么破?
  • 换了系统想继续之前的写作怎么破?
  • 纯粹就是想多客户端写作怎么破?

我就纯属蛋疼的。喜欢在办公和休息的地方都写作;或者我一win本
一mac 都想写文章。但Hexo的静态部署的原则不像WordPress一样,能关联博客地址,利用数据库进行博客更新。好了,这里就来解决这个问题。┑( ̄Д  ̄)┍

阅读全文 »

Effective Java--Builer构造器

发表于 2016-04-22   |   分类于 代码狗 , 学习log   |  

一个实体类往往有不同的属性 属性有的用于构造器 视为构造时的必需参数 而有的可有可无 类似json和xml一般,有多少个属性,每个属性有多少个赋值都不确定 。e.g.动物 名称string name和是否有尾巴istail是必须的,是否吃草iseatgrass 多重weight 交配手段sexmethod 科目等为非必须字段。解决这一构造问题一般有三种方式。

阅读全文 »

删除Sdf文件导致转到定义失效

发表于 2016-04-22   |   分类于 什么都学一下 , 学习log   |  

cmomit的时候发现一个.sdf的文件特别大,项目才不到2m,一个sdf就30多m了。能不能删?
谷歌了一下,提示sdf文件和iph文件是存放预编译头和Intellisense的。

阅读全文 »

12…8
Jay Wang

Jay Wang

你猜?

111 日志
11 分类
62 标签
RSS
GitHub Weibo douban Instagram Google
© 2018 Jay Wang
由 Hexo 强力驱动
主题 - NexT.Muse