精华内容
下载资源
问答
  • 各版本c++ 版本python 版本 ...最容易想到的就是每次将数组的元素右移一位,循环K次。 #include<iostream> using namespace std; void RightShift(int *arr, int N, int K){ while(K--){ ...

    c++ 版本

    题目描述:
    设计一个算法,把一个含有N个元素的数组循环右移K位。

    解法一:
    最容易想到的就是每次将数组中的元素右移一位,循环K次。

    #include<iostream>
    using namespace std;
    void RightShift(int *arr, int N, int K){
         while(K--){
              int t = arr[N-1];
              for(int i = N-1;i>0;i--){
                    arr[i]=arr[i-1];
              }
              arr[0]=t;
        }
     }
    
    int main(){
       int num[4] = {1,3,7,9};
       for(int i = 0; i < 4;i++)
       	   cout<<num[i]<<' ';
       cout<<'\n';
       RightShift(num,4,2);
       for(int i = 0; i < 4;i++)
          cout<<num[i]<<' ';
          }
    

    解法二:
    用空间来换时间,申请一个大小为K%N的数组,因为循环移位K次,如果K > N,则其效果与移动K%N次是一样的。所以在解法一,我们可以加上 K = K %N 这句。
    假如原数组: 1 2 3 4 5 6 7 需要右移4次,那么我们想要的结果是: 5 6 7 1 2 3 4
    我们注意到,其实就是将1234前四个元素拿出来(变成array A: _ _ _ _ 5 6 7, array B:1 2 3 4),然后将567前移充填(A 变成 5 6 7 _ _ _ _),然后我们只要将 B 数组再添加到A 数组后面就完成了。 最后 (A : 5 6 7 1 2 3 4)

    void RightShift(int *arr, int N, int K){
         K = K % N;
         int *sp = (int*)malloc(K*sizeof(int));
         int i = 0,s = 0;
         for(; i < K;i++){        // 将数组前K 位存入sp中
             sp[i] = arr[i];
         }
         for(;i<N;i++,s++){       // 将数组第K+1 - N 位移到arr前端。
            arr[s] = arr[i];
         }
         for(i = 0; s < N;i++,s++){    // 将sp中的数取出,拼入arr数组。
            arr[s] = sp[i];
         }
    }
    

    这里对数组进行了复制K次,将后面的元素前移N-K次,然后再将K 个元素拼接到数组后面进行了K次操作,一共进行了N+K次操作。然而空间复杂度为K.
    解法三:
    这里有一个很巧妙的方法来实现数组循环。
    假如原数组: 1 2 3 4 5 6 7 需要右移4次,那么我们想要的结果是: 5 6 7 1 2 3 4。
    1.将1234逆置 变成 4321
    2.将567逆置 变成 765
    3.将两个逆置数组拼接: 4321765
    4.将这个已拼接的数组逆置: 5671234 就成了我们想要的结果了。

    void Reverse(int *arr,int start,int end){      //逆置
        for(; start < end;start++,end--){
               int s = arr[end];
               arr[end] = arr[start];
               arr[start] = s;
          }
    }
    
    void RightShift(int* arr,int N, int K){
          K = K%N;                       //对应上文步骤
          Reverse(arr,0,K-1);           //1 
          Reverse(arr,K,N-1);           //2
          Reverse(arr,0,N-1);           //4
    }
    

    上述算法Reverse函数时间复杂度分别为K/2, (N-K)/2,N/2, 所以总的复杂度为O(N),空间复杂度为O(1)

    python 版本

    通过python的切片以完成循环操作的核心,这种办法更类似于c++的解法二。
    算法提供三个参数,输入数组,步数和移动的方向。

    def loop_list(target: list, times: int = 1, direction: bool or int = 0):
        """
        :param target: input list
        :param times: loop times
        :param direction: 1 for left ; 0 for right
        :return: loop list
        """
        times = times % len(target)
        if direction:
            return target[times:] + target[:times]
        else:
            return target[-times:] + target[:-times]
    

    参考文章:https://blog.csdn.net/mayh554024289/article/details/47914237

    展开全文
  • 一个数在计算机的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1. 比如,十进制的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3...

    一. 机器数和真值

    在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.

    1、机器数
    一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.

    比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。

    那么,这里的 00000011 和 10000011 就是机器数。

    2、真值
    因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

    例:
    0000 0001的真值 = +000 0001 = +1,
    1000 0001的真值 = –000 0001 = –1
    原码, 反码, 补码的基础概念和计算方法.


    二.原码反码补码概念

    计算机中二进制相加逢二进一
    在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.

    原码:

    原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

    [+1]原 = 0000 0001
    
    [-1]原 = 1000 0001
    

    第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

    [1111 1111 , 0111 1111

    [-127 , 127]

    原码是人脑最容易理解和计算的表示方式.

    反码

    反码的表示方法是:

    • 正数的反码是其本身

    • 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

    [+1] = [00000001]原 = [00000001]反

    [-1] = [10000001]原 = [11111110]反

    可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

    补码

    补码的表示方法是:

    • 正数的补码就是其本身

    • 负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

    [+1] = [00000001]原 = [00000001]反 = [00000001]补

    [-1] = [10000001]原 = [11111110]反 = [11111111]补

    对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.


    三. 为何要使用原码, 反码和补码

    现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:

    [+1] = [00000001]原 = [00000001]反 = [00000001]补
    

    所以不需要过多解释. 但是对于负数:

    [-1] = [10000001]原 = [11111110]反 = [11111111]补
    

    那有了原码,为什么还需要补码和反码呢?为什么负数需要反码和补码的表示形式呢?
    计算十进制的表达式:1+1=2

    1 + 1 = [00000001]原 + [00000001]原 = [00000010]原 = 2 
    

    从上面来看十进制只是完成了两个正数的相加,但是看下面:

    计算十进制的表达式: 1-1=0

    1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 
    =  [10000010]原 = -2
    

    如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.

    为了解决原码做减法的问题, 出现了反码:

    计算十进制的表达式: 1-1=0

    1 - 1 = 1 + (-1) 
    = [0000 0001]原 + [1000 0001]原
    = [0000 0001]反 + [1111 1110]反 
    = [1111 1111]反 
    = [1000 0000]原 = -0
    

    发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.

    于是补码的出现, 解决了0的符号以及两个编码的问题:

    1-1 = 1 + (-1) 
    = [0000 0001]原 + [1000 0001]原 
    = [0000 0001]补 + [1111 1111]补 
    = [0000 0000]补
    =[0000 0000]原
    =0
    

    这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

    (-1) + (-127) 
    = [1000 0001]原 + [1111 1111]原 
    = [1111 1111]补 + [1000 0001]补 
    = [1000 0000]补
    =-128
    

    -1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)

    使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

    因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

    四.左移<<,右移>>,和无符号右移>>>

    根据上面的结论可以知道,计算机底层使用的是补码的方式进行运算的。

    计算十进制表达式:4/4=2

    //换成位移运算(右移两位相当于:4/(2*2))
    4/4 = 4>>2
    //转换成二进制补码运算(正数的原码反码补码相同),也就是4的二进制右移两位。
    =00000100[补]
    //正数右移后高位补零
    =00 000001
    //换算成十进制
    =1
    

    计算十进制表达式:-4/2=-2

    //换算成位运算
    -4/2 = -4>>2
    //转换成二进制补码运算(负数的补码:符号位不变,其余的取反然后加1)
    =10000100[原] = 11111100[补]
    //负数右移两位后高位补1,因为要保证符号为负 即1
    =11 111111[补]
    //负数得到运算后的补码需要转回原码然后转成十进制(符号位不变,然后取反+1)
    =10000001[原]
    //换算成十进制
    =-1
    

    计算十进制表达式:1*4=4

    //换算成位运算(左移两位相当于:1*(2*2))
    1*4 = 1<<2
    //转换成二进制补码运算
    =00000001[补]
    //左移两位低位补0
    =000001 00[补]
    //转换成十进制
    =4
    

    计算十进制表达式:-1*4=-4

    //换算成位运算
    -1*4 = -1<<2
    //换算成二进制补码运算
    =10000001[原] = 11111111[补]
    //左移两位低位补0
    =111111 00[补]
    //转换成原码(负数补码取反加1 = 原码)
    =10000100[原]
    //转换成十进制
    =-4
    

    无符号右移

    无符号右移,不论正负高位统一补0

    计算无符号右移:4>>>2

    4>>>2
    //换算成二进制补码运算
    =00000100[补]
    //开始右移两位
    =00000001[补]
    //换算成十进制
    =1
    

    计算无符号右移:-4>>>2

    -4>>>2
    //换算成二进制补码运算
    =10000100[原] = 11111100[补]
    //开始右移两位,无符号右移中无论正负高位统一补0
    =00111111[补]
    //换算成十进制,int类型是32位,以上举例统一用8位只是方便计算。
    =1073741823
    

    从上面的无符号运算来看,正数的无符号右移和带符号右移的结果是一样的,因为带符号右移的时候也是高位补0,负数在带符号右移的时候是高位补1的,所以负数得到的结果是不会相同的。

    展开全文
  • 本资源用于实现单片机,带左移右移功能的大液晶程序,C语言编程
  • AD转换中左移右移操作符知识

    千次阅读 2015-07-19 16:32:14
    左移几位就除以2的几次方右移几位就乘以2的几次方 如:36>>2=9 36 有AD功能的单片机如12c5a60s2在输出AD转换结果时就用到这个知识点。 当ADRJ=0时,转换结果的高8位存储在ADC_RES,低2位存储在ADC_RESL,要输出10...

    左移几位就除以2的几次方右移几位就乘以2的几次方

    如:36>>2=9

    36<<2=144


    有AD功能的单片机如12c5a60s2在输出AD转换结果时就用到这个知识点。

    当ADRJ=0时,转换结果的高8位存储在ADC_RES中,低2位存储在ADC_RESL中,要输出10位转换后的数据用这条语句:

    result=ADC_RES*4+ADC_RESL;

    当然,这是10位的二进制数,还得换算回去:realresult=result*vcc/1024;

    用byte类型就装不下啦,如果不想要太高的精度可以舍掉低2位,毕竟低2位只影响到小数点后2位的精度。这时就要这样写:

    result=ADC_RES*4,换算公式如上。


    当ADRJ=1时

    转换结果的高2位存储在ADC_RES中,低8位存储在ADC_RESL中,看懂上面的知识,这里就会了,不多说.

    展开全文
  • 32 【程序 32 左移右移】 题目:取一个整数 a 从右端开始的 4~7 位。 程序分析:可以这样考虑: (1)先使 a 右移 4 位。 (2)设置一个低 4 位全为 1,其余全为 0 的数。可用~(~0<<4) (3)将上面二者进行&...

     

    32 【程序 32 左移右移】

    题目:取一个整数 a 从右端开始的 4~7 位。

    程序分析:可以这样考虑:

    (1)先使 a 右移 4 位。

    (2)设置一个低 4 位全为 1,其余全为 0 的数。可用~(~0<<4)

    (3)将上面二者进行&运算。

     

    package cskaoyan;
    
    public class cskaoyan32 {
    	@org.junit.Test
    	public void logicalShift() {
    		java.util.Scanner in = new java.util.Scanner(System.in);
    		System.out.println("input a number:");
    		int a = in.nextInt();
    		int b = a >> 4;
    		int c = ~(~0 << 4);
    		int d = b & c;
    		System.out.println(a + " " + d);
    
    		in.close();
    	}
    }
    

     

    转载于:https://www.cnblogs.com/denggelin/p/11427487.html

    展开全文
  • 2个led灯先左移,然后右移,然后同时闪烁。使用多个for循环实现。
  • java移位运算<<左移 >>右移 <<<无符号右移 详解概念代码举例过程解释<<左移>>右移>>>无符号右移实际应用 概念 <<:左移 左边最高位丢弃,右边补齐0 >>:右移...
  • 重载左移右移操作符的意义:对于自定义类型的变量,c++编译器只能编译输出基础类型变量,所以想要输出自定义类型的对象元素就需要重载输出流操作符 操作符的重载一般情况下是使用成员函数进行重载,在一些特殊情况...
  • 调用#include 头文件,使用左移右移命令
  • NEON的移位指令和ARM指令的标量移位,把向量的各个元素左移或者右移若干比特。那些移到临近元素的比特会被丢弃掉,不会影响到邻近元素的移位结果。移位操作的移位数可以直接编码到指令里,或者用 一个指定的...
  • 友元函数实现左移右移操作符重载
  • 如下是源代码://=============================================================//程序名:LLL22_4.C//程序功能:流水灯控制左移 右移//==============================================================#include/...
  • NEON的移位指令和ARM指令的标量移位,把向量的各个元素左移或者右移若干比特。那些移到临近元素的比特会被丢弃掉,不会影响到邻近元素的移位结果。移位操作的移位数可以直接编码到指令里,或者用 一个指定的...
  • c++整数在内存的存储(左移右移)

    千次阅读 2014-09-30 10:29:23
    左移相对比较简单,是不考虑符号位的,符号位也会被移除,正数可能左移成负数,负数也可能编程正数 而右移呢,就需要考虑符号位了。右移过程符号位保持不变,但注意符号位如果是1也是右移给右侧一位...
  • 使用左移右移而不使用直接置位

    千次阅读 2017-05-17 19:48:47
    这个操作就是将BSRR寄存器的第pinpos位设置为1,为什么要通过左移而不是直接设置一个固定的值呢?其实,这是为了提高代码的可读性以及可重用性。这行代码可以很直观明了的知道,是将第pinpos位设置为1。 如果你写成...
  • 答:右移左移符号,让当前值右移或者左移 问:怎么用?答:eg:(eg是举个例子的意思) int a=0xFF//a是十六进制的数,它是存在寄存器里的,对应的二进制数就是1111 1111 a&lt;&lt;1;//a的位变为0x...
  • 做单一灯的左移右移,硬件电路如图4.4.1所示,八个发光二极管L1-L8分别接在单片机的P1.0-P1.7接口上,输出“0”时,发光二极管亮,开始时P1.0→P1.1→P1.2→P1.3→┅→P1.7→P1.6→┅→P1.0亮,重复循环。...
  • 右移的应用场景:当要计算某个数除以2的N次方的时候就用右移,效率最高 0000 0000 0000 0000 0000 0000 0000 0000 000000 0000 0000 0000 0000 0000 0000 10 位运算练习(重要) 1、将一个整数以二进制方式...
  • 移位运算(左移右移)这是网上流传的“变态级JAVA程序员面试32问”的其中一题(二十八题),然后下面给出来的答案是第二十八,编程题: 用最有效率的方法算出2乘以8等於几?有C背景的程序员特别喜欢问这种问题。答案: ...
  • 1.左移<< 不区分正负数 左移运算符 m <<n表示把 m 左移 n 位。在左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。 public class Test { public static void main(String[] args) { int i =6...
  • C51和C语言左移右移

    千次阅读 2020-03-16 21:19:49
    C51中左移右移有两种方式 一:(其实应该叫循环左移和循环右移) “_crol_(移动对象,左移的位数)"是左移函数,操作效果是:向左移动,最高位移动到最低位。 例如: 1110左移一位? _crol_(1110,1);——移动后是...
  • c语言中左移右移操作

    千次阅读 2014-11-24 17:33:39
    在C左移是逻辑\算术左移(两者完全相同),右移是算术右移,会保持符号位不变。实际应用可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多。
  • 左移右移

    2017-06-18 10:04:31
    左移右移几乎每个编程语言都会涉及左移右移左移以Python为例:>>> print(2) 4 >>> print(64) 128 >>> bin(64) # 查看64的二进制 '0b1000000' >>> bin(128) # 查看128的二进制 '0b10000000'a表示将a的二进制...
  • 下面有几个是注意的地方: 1. 不管是算术左右移和逻辑左右移,最好是unsigned类型,因为这样算术与逻辑是一样的结果。...3. 编程过程,一定要注意右移操作,注意signed 和unsigned的区别。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,892
精华内容 7,956
关键字:

编程中左移右移