算法总结三

unsigned char a=0xA5;

unsiged char b=~a>>4+1;

求b

解:unsigned char只能表示低八位,1个字节八位,这里0x表示十六进制,所以从0000到1111为16位,4位表示1位,C++中&&和 ||表示bool之间的与和或,&和 | 表示位运算的与和或,符号优先级顺序,加号大于移位运算符大于取反运算符    因此4+1=5,A5=1010 0101 右移五位=0000 0101取反=1111 1010因为b是unsigned char因此全是正的,为250

 

关于位运算一共有与,或,异或,左移,右移

位运算效率比除2乘2快许多,如果9与1,那么为1001&1也即为1,8与1为1000&1为0,

例题:
求出一个数的二进制中1的个数:将一个整数最后一位和1相与,然后右移一位

因为一个大于0的整数至少有1个1,那么从右往左找到第一个1,该数-1,表示该位为0,后面的位全部从0变为1,也即从右往左找到第一个1,该数-1表示该位左边不变,右边取反,注意两个取反的数相与得0,把原来的数和该数-1相与,左边部分不变,右边部分为0,

 

例题

1010和1101比较,我们发现都是1和都是0就不移动设为0,01和10就是移动设为1,那么是异或预算

 

char s[]="0123456789";      sizeof(s)=11        sizeof(*s)=1     //因为最后还有个\0位置,   

int s[100]="0123456789"   sizeof(s)=400    

数组new出的数组大小比如是char[] s=new char[2];   那么只给s[0],s[1]开辟内存,s[2]没有开辟内存

 

执行GetMemory(str); 

void GetMemory (char*p, int num){

  p=(char * )malloc(size of(char)*num);

}                             //这里的意思是传入str字符串为其开辟内存,但是,由于函数中形参的副本机制,没有返回指针,因此不能达到效果,每次执行一次函数就会申请一次内存,但是内存却不能有效释放,结果是内存一直被占用,造成内存泄漏

如果str为字符串,那么*str为第一个首字母而不是整个字符串的内容

 

c#

数组中str.length获取到的是数组初始化分配的大小,不是元素不为空的大小,因此,可以改用list,再用list.length

 

构造函数没有返回值,别犯二,public 函数名(){},还有static在public的后面,public static

二维数组初始化

 

  1.             //规则二维数组的定义和初始化  
  2.             int[,] Arr = new int[2, 5] { { 1, 2, 3, 5, 6 }, { 1, 2, 3, 4, 5 } }; 

 

如果二维数组初始化,指定了行和列的大小必须上面的方法,如果只是指明了行的大小,那么下面每一行都要初始化数据,根据数据大小判断多少列

  1.             //不规则二维数组  
  2.             int [][] arr = new int [3][ ];  //表示含有三个一维数组的数组 
  3.             arr[0] = new int[5]{1,2,3,4,5};  

最后一行是一维数组的初始化,把整个数组放到后面

 

int[] numbers = new int[5] {1, 2, 3, 4, 5};       或     int[] numbers ={1, 2, 3, 4, 5};

得到二维数组的行数和列数:

 

p.getlength(0);
p.getlength(1);
0代表的行数,1代表的列数
p.getlength(1);
0代表的行数,1代表的列数
<span style="color:#5a676f">输入一个整数,输出该数二进制表示中1的个数</span>

 public static int GetResult(int target)
        {
            int n = 2;  //2为底数
            int res = 0; //为多少个1
            while (true)     //注意递归和迭代中迭代方式必须用while(true)来作为退出条件,不能用Math.Pow(n, m)作为退出条件
            {
                int m = 0;  //m为幂
                if(target==0){
                    break;
                }
                while (target >= Math.Pow(n, m))
                {
                    m += 1;
                }
                target -= (int)Math.Pow(n, m-1);
                res += 1;
            }
            return res;
          }   


剑指offer:

 

如果错误在于

应该是如果传参传的是对象本身而不是引用会调用拷贝构造函数

1 .

3.

 

4.

最后说下return this和return *this的区别,

class A  
{  
public:  
    int x;  
    A* get()  
    {  
        return this;  
    }  
};  

如果返回this,返回当前对象的地址,所以要拿A*接收

class A  
{  
public:  
    int x;  
    A get()  
    {  
        return *this; //返回当前对象的拷贝  
    }  
};  

如果返回的是*this,那么返回的是对象的引用,所以要用A&或者A来接收

c# internal关键字:

只有在同一程序集的文件中,内部类型或成员才可访问

 

Console.WriteLine("{0}{1}")中的{0}{1}是什么意思?

Console.WriteLine("{0}{1}",1,2);
会输出 12
Console.WriteLine("{0}{1}","1234",2);
会输出 12342
{0}表示第1个输出对象,{1}表示第2个输出对象,当然如果{0},{1}那么输出的是1234,2

 

C#中ref和out的作用

在C#中通过使用方法来获取返回值时,通常只能得到一个返回值。因此,当一个方法需要返回多个值的时候,就需要用到ref和out

ref代码演示:

 static void Main(string[] args)
        {
            int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            float avg = 0; //注意在传入ref类型的形参时,必须对它们进行初始化
            int max = 0;
            int min = 0;
            int sum = GetIntResult(arr, ref avg, ref max, ref min);
            Console.WriteLine("和:{0}\t平均值:{1}\t最大值:{2}\t最小值:{3}", sum, avg, max, min);
            Console.Read();
        }

        static int GetIntResult(int[] arry, ref float avg, ref int max, ref int min)
        {
            int sum = 0;
            max = arry[0];
            min = arry[0];
            for (int i = 0; i < arry.Length; i++)
            {
                sum += arry[i];

                if (max < arry[i])
                {
                    max = arry[i];
                }
                if (min > arry[i])
                {
                    min = arry[i];
                }
            }
            avg = sum / arry.Length;
            return sum;
        }


可以看到,调用完ref参数的函数,虽然返回的不是ref的参数,但是主函数仍然能把在调用函数修改后的值输出出来

 

out代码:

 int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
             float avg;//在使用out关键字时,不需要在此处初始化,但要在函数中初始化
             int max;
             int min;
             int sum = GetIntResult(arr, out avg, out max, out min);

结果和上面一样。

 

结论:

       关键字“ref“和”out”之间的唯一区别就是关键字ref要在传参前初始化,out在函数中初始化

C#中的ref和out提供了值类型按引用进行传递的解决方案,ref和out关键字将告诉编译器,现在传递的是参数的地址而不是参数本身,现在用ref和out修饰后,传递的就是这个指针,所以可以实现修改后a,b的值真正的交换。这就是ref和out给我们带来的好处。

 

算法:实现一个函数,把字符串中的每一个空格替换成”%20”。

第一个种方法:遍历每一个字符(第一个for循环),当遇到空格的时候后面的数整体移动3个单位(第二个for循环),时间复杂度为n2

更好的办法是:只使用一层for循环,用另一个数组接收这个数组的每一个值,将移动数组的语句变成赋值语句,并用2个变量保存接收到2个数组当中的第i位,当接收到空格,新数组加上”%20”,i+=3;即可,时间复杂度为n

 

判断两个小数是否相等的时候,比如float和double类型,不能直接d1==d2,要用他俩只差的绝对值是否在一个很小的范围内

 

排序:

我们可以看到时间复杂度要求这么低,很直观得到需要将一部分的时间复杂度转成了空间复杂度,也即牺牲一部分内存来得到运算效率。

如果是O(n)那也就是遍历一次一个for循环,那么第一次遍历所有数,找到最大值和最小值,第二次用一个新数组,开辟大小为(最大值-最小值)。

那么第0个位置放最小值有几个,第1个位置放最小值+1有几个,遍历需要排序的数,依次记录每个数有多少个,依次放到新数组中,遍历新数组,依次输出元素>0的记为排序后的

总结:要想把时间复杂度降下来,用一个数组接收最小值到最大值之间所有可能,记录每个元素出现次数即可,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值