zoukankan      html  css  js  c++  java
  • 指针和引用的区别

    指针是一个变量,其存储的是一个地址,指向内存的一个存储单元。引用(c++具备)跟原变量实质是同一个东西,只不过是原变量的一个别名,在内存中占同一个存储单元。
    指针可以有多级,但引用只能有一级
    指针可以为空,但引用值不能为NULL,并且引用在定义的时候必须初始化;
    指针在初始化后可以改变,引用在初始化后不能再改变

    1、二分查找的实现

    #include<stdio.h>
    int BinSearch(int arr[],int len,int key)                          //折半查找法(二分法)
    {
        int low=0;                         //定义初始最小
        int high=len-1;                 //定义初始最大
        int mid;                            //定义中间值
        while(low<=high)
        {
            mid=(low+high)/2;              //找中间值
            if(key==arr[mid])               //判断min与key是否相等
                return mid;    
            else if(key>arr[mid])             //如果key>mid  则新区间为[mid+1,high]
                low=mid+1;
            else                                       //如果key<mid  则新区间为[low,mid-1]
                high=mid-1;
        }
        return -1;                             //如果数组中无目标值key,则返回 -1 ;
    }
    int main()
    {
        int arr[]={1,2,3,4,5,6,7,8,9,10,11};                      //首先要对数组arr进行排序
        printf("%d 
    ",BinSearch(arr,(sizeof(arr)/sizeof(arr[0])),7));
        return 0;
    }

    2、求给定一个整形数,如何求出其二进制数1的个数

    前言:一个数要存储在计算机中,是以该数二进制补码形式存储的。

    注意题目没注明不排除为负整数

    法1)

    思路:我们发现一个数和该数减1后做按位与操作再赋给该数,即某数=某数&(某数-1),每执行一次,该数二进制最右边的1就会丢掉。那么我们便可以知道,只要一个数在变成0之前能执行多少次某数=某数&(某数-1)操作,该数的二进制便有多少个1。

    int main()
    {
        int x = 9999;
        int countx = 0;
        while(x)
        {
            countx++;
            x = x&(x-1);
        }
        cout<<countx<<endl;
        return 0;
    }

    此方法既适用于负数,又大大提高了程序执行的效率。

    法2)思路:如果一个数与1作与运算则可以发现该数最后一位数为1,否则为0. 

    #include <iostream>
      using namespace std;
    
      int main()
      {
          int n = 0;
          cout << "输入一个数";
          cin >> n;
          int count = 0;
          while (n)
     {
          if (n & 1)
          {
              count++;
          }
          n >>= 1;
      }
          cout << "1的个数为"<<count<<endl;
          return 0;
      }

    但是此方法存在缺陷如果输入的数为负数则会无限死循环

    //必须要循环32次,效率太低

    法3)首先把n与1做与运算,判断n的最低位是不是为1。接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1….这样反复左移,

    每次能判断n的其中一位是不是1.这个解法中循环的次数等于整数二进制的位数,32位的整数需要循环32次

    #include <iostream>
      using namespace std;
    
      int main()
      {
          int n = 0;
          int key = 1;
          cout << "输入一个数";
          cin >> n;
          int count = 0;
          while (key)
     {
          if (n & key)
          {
              count++;
          }
          key <<= 1;
      }
          cout << "1的个数为"<<count<<endl;
          return 0;
      }

    缺点同上是效率低

    法4)

    (不推荐使用):

    思路:当我们想要得到一个十进制数的每一位时,通常是采用模10除10的方法,模10得到最低位,除10得到高位,一直重复。那么想要得到一个数的二进制的每一位时,也可以采用模2除2的方法。

     
    //求一个数存储在二进制数中1的个数(补码形式存储,所以算的是该数二进制补码中1的个数)
     
    int count_one1(int m)   //不适用于负数
    {
        int count = 0;
        while (m)   
        {
            if (m % 2 == 1)   //最低位是1
            {
                count++;
            }
            m /= 2;  //处理完最低位后将其丢掉
        }
        return count;
    }
    int main()
    {
        int n = 1;
        int count = count_one1(n);
        printf("%d
    ", count);
        system("pause");
        return 0;
    }

    但我们发现,一个负数不论%2还是/2结果永远是负数,所以用上述代码求解1的个数时永远都是0个,所以此种方法只适用于正数。

  • 相关阅读:
    约合¥1720 LG法国称G Watch将于6月开卖
    c语言中的位移位操作
    兼容的动态加载JS【原】
    Oracle 10g AND Oracle 11g手工建库案例--Oracle 10g
    面向对象思想----不看懊悔!
    学习设计模式--观察者模式(C++)
    使用POI 导入excel
    机器学习 F1-Score, recall, precision
    阿里无线11.11:手机淘宝移动端接入网关基础架构演进之路
    ICE 迁移64位安装问题
  • 原文地址:https://www.cnblogs.com/kunx/p/12795616.html
Copyright © 2011-2022 走看看