zoukankan      html  css  js  c++  java
  • 转:位运算,常见用法集 狼

    位运算神马的,最给力了,当你的复杂度优化到不能再优的时候,你还可以考虑位运算,把本来小时级别的运算提高到秒级别。

    比如6400个bool值向量,你要窜位比较相似度O(n^2)复杂度不能再优化的情况下,需要6400*6400=4千万次比较,如果变成Ulong 64位的,每次O(1)比较64位,就可以把复杂度压缩到O(n^2/64/64),时间压缩4000倍!

    本来小时级别的运算提高到秒级别。

    参考我另外一个文章,位运算技巧总结:

    http://blog.csdn.net/superdullwolf/archive/2009/10/10/4649080.aspx

    下面是C#的一些实验。

    using System;
    using System.Text;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    //TestBitOpration();
    //swap();
    //Judge();
    //MeanInt();
    //power();
    //abs();
    //mod();// 没有得出正确的输出
    //multi();// 不够完美
    //division();
    //oppo();
    comple();
    }
    private void swap()
    {
    int op1 = 31, op2 = 33;
    // 位运算实现交换操作
    //先做出俩个整数的异或,交换时和另外一个再做次异或就可实现交换了
    op1 = 31 ^ 33 ^ 31; //op1变成33
    op2 = 31 ^ 33 ^ 33; //op2变成31
    MessageBox.Show(Convert.ToString(op1));
    MessageBox.Show(Convert.ToString(op2));
    }

    public void TestBitOpration()
    {

    //二进制位运算
    int op1 = op2 = 8;//1000
    op1 = op1 ^ 1; //和1做异或时,奇数减1,偶数加1 1001
    op2 = op2 & 1; //都为1的才为1;0
    op1 = op1 | 1; //有一个为1就为1;1001
    op1 = op1 << 1; //10010
    op2 = op2 << 1; //0

    this.richTextBox1.AppendText(Convert.ToString(op1, 2) + "\n");
    // this.richTextBox1.AppendText(Convert.ToString(op2, 2) + "\n");

    /*
    //提取某个整数的某一二进制位
    int [] kbit=new int[sizeof(int)];
    int k;
    for (k = 0; k <=sizeof(int); k++)
    {
    kbit[k] = op1 >> k & 1;
    MessageBox.Show(Convert.ToString(kbit[k]));
    }
    */
    //对int型变量的第3位清0or1
    MessageBox.Show(Convert.ToString(op1, 2));
    op1
    = op1 & ~(1 << 3); //置0 向左移三位,是第四位
    MessageBox.Show(Convert.ToString(op1, 2));
    op1
    = op1 | (1 << 3);//置1
    MessageBox.Show(Convert.ToString(op1, 2));


    }

    private void Judge()
    {
    //判断奇数还是偶数
    int op = 8;
    string output = "";
    if ((op & 1) == 0)
    {
    output
    = "op is 偶数";
    MessageBox.Show(output);
    }
    if ((op & 1) == 1)
    {
    output
    = "op is 奇数";
    MessageBox.Show(output);
    }
    }
    private void MeanInt()
    {
    //计算整数的平均值
    int mean, op1 = 8, op2 = 18;
    mean
    = (op1 & op2) + ((op1 ^ op2) >> 1);//还没想明白原理
    MessageBox.Show(Convert.ToString(mean));

    }
    //判断op>0 是不是2 的整数幂
    private void power()
    {
    int op = 18;
    string output = "";
    if ((op & (op - 1)) == 0)
    output
    = "op 是2的整数幂";
    else
    output
    = "op 不是2的整数幂";
    MessageBox.Show(output);
    }
    private void abs()
    {
    //绝对值运算,原理还没掌握
    int abs, op = -18;
    MessageBox.Show(Convert.ToString(op));
    abs
    = op >> 31;
    MessageBox.Show(Convert.ToString(abs));
    abs
    = (op ^ abs) - abs;
    MessageBox.Show(Convert.ToString(abs));
    }

    private void mod()
    {
    int a = 65, n = 3;
    int c;
    c
    = a % (2 ^ n);
    MessageBox.Show(Convert.ToString(c));
    c
    = a & (2 ^ n - 1);
    MessageBox.Show(Convert.ToString(c));
    }
    private void multi()
    {
    int op1 = 8, n = 2;
    int result;
    result
    = op1 * 4;
    MessageBox.Show(Convert.ToString(result));
    result
    = op1 << n;
    MessageBox.Show(Convert.ToString(result));
    }
    private void division()
    {
    int op1 = 8, n = 2;
    int result;
    result
    = op1 / 4;
    MessageBox.Show(Convert.ToString(result));
    result
    = op1 >> n;
    MessageBox.Show(Convert.ToString(result));

    }
    private void oppo()
    {
    int op=9;
    int result=(~op+1);
    MessageBox.Show(Convert.ToString(op));
    MessageBox.Show(Convert.ToString(result));
    }
    private void comple()
    {
    int op1=9, op2,op3,op4;
    MessageBox.Show(Convert.ToString(op1,
    2));
    op2
    = ~op1;
    op3
    = ~op1 + 1;
    op4
    = (1 >> 32) - 9;
    MessageBox.Show(Convert.ToString(op2,
    2));
    MessageBox.Show(Convert.ToString(op3,
    2));
    MessageBox.Show(Convert.ToString(op3));
    MessageBox.Show(Convert.ToString(
    -9, 2));
    MessageBox.Show(Convert.ToString(op4));
    MessageBox.Show(Convert.ToString(op4,
    2));
    MessageBox.Show(Convert.ToString(
    -2,2));
    }

    public static bool Is1AtKPos(ulong u, int k)
    {
    return ((u >> (k - 1)) & 1ul) == 1ul;
    }

    //判断一个ulong数字里有几个1
    public static int MatchDegree(ulong u)
    {
    u
    = (u & 0x5555555555555555) + ((u >> 1) & 0x5555555555555555);
    u
    = (u & 0x3333333333333333) + ((u >> 2) & 0x3333333333333333);
    u
    = (u & 0x0F0F0F0F0F0F0F0F) + ((u >> 4) & 0x0F0F0F0F0F0F0F0F);
    u
    = (u & 0x00FF00FF00FF00FF) + ((u >> 8) & 0x00FF00FF00FF00FF);
    u
    = (u & 0x0000FFFF0000FFFF) + ((u >> 16) & 0x0000FFFF0000FFFF);
    u
    = (u & 0x00000000FFFFFFFF) + ((u >> 32) & 0x00000000FFFFFFFF);
    return Convert.ToInt32(u);
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    public int op2 { get; set; }

    private void richTextBox1_TextChanged(object sender, EventArgs e)
    {

    }
    }


    }
  • 相关阅读:
    Ubuntu20.04本地安装Redash中文版
    ubuntu设置root密码
    qmake设置生成文件分类
    QML对象的构造函数和析构函数
    QString使用split按照某字符进行分解
    Qt的qDebug直接打印不添加头文件
    C++宏定义中的#
    Qt设置生成的文件路径
    QWidget禁止最大化
    js-去掉回车和空格
  • 原文地址:https://www.cnblogs.com/gowhy/p/2094029.html
Copyright © 2011-2022 走看看