C/C++如何实现循环左移,循环右移

2022-07-22 13:12:38
目录
实现对一个无符号数的循环左移和循环右移循环移位直接可用的函数(循环右移、循环左移)整体代码本文的小技巧注意的地方字符串循环左|右移实现(C/C++)字符串循环右移K位字符串循环左移K位循环左右移结果相同条件

实现对一个无符号数的循环左移和循环右移

循环移位直接可用的函数(循环右移、循环左移)

    //val表示需要移位的数>//字节数乘以8代表一共多少位//向右循环移n位的结果:假设数据一共size位,向左移size-n位,再与原数右移n位进行或操作的结果
    //val表示需要移位的数 n表示移位位数
    //字节数乘以8代表一共多少位
    //向右循环移n位的结果:假设数据一共size位,向左移size-n位,再与原数右移n位进行或操作的结果
    uint32 bit_move(uint32 val, int n) {
        uint32 size = sizeof(val) * 8;
        n = n % size;
        //return (val >> (size - n) | (val << n));//左移
        return (val << (size - n) | (val >> n));//右移
    }

    整体代码

    如果出现头文件报错,去我主页搜关键词“bits/stdc++.h”

    #include<bits/stdc++.h>
     
    using namespace std;
     
    typedef unsigned short int uint16;
    typedef unsigned int uint32;
     
    uint32 bit_move(uint32 val, int n) {
        uint32 size = sizeof(val) * 8;
        n = n % size;
        //return (val >> (size - n) | (val << n));
        return (val << (size - n) | (val >> n));
    }
     
    int main() {
        uint16 a;
        //cin >> hex >> a;
        scanf_s("%hd", &a);//16进制的两种输入方式 (这个地方如果是十进制输入,会栈溢出,为什么?)
        cout << "原始数据的二进制16位表示:  " << bitset<16>(a) << endl;
        uint32 a1 = (uint32)a;
        cout << "转换为32位后,右移之前的值:" << bitset<32>(a1) << endl;
        uint32 res = bit_move(a1, 2);
        cout << "右移2位后结果:             " << bitset<32>(res) << endl;
        //for (int i = 1; i < 3; i++) {
        //    a1 = bit_move(a1, 1);
        //    cout << "右移"<< i << "位后结果:           "<< bitset<32>(a1) << endl;
        //}
        return 0;
    }

    执行结果

    2
    原始数据的二进制16位表示:  0000000000000010
    转换为32位后,右移之前的值:00000000000000000000000000000010
    右移2位后结果:             10000000000000000000000000000000

    本文的小技巧

    输入16进制的方式

    cin >> hex >> a;
    scanf_s("%hd", &a)

    int型 输出x位二进制的方式

    cout << bitset<32>(x) << endl;//如果输出64位,则填64

    注意的地方

    这个地方如果是十进制输入,会栈溢出,为什么?因为定义在栈上的局部变量a为16位,如果按%d输入,则会占用32位,这样的话程序运行结束系统只会处理16位,剩下的16位就破坏了堆栈

    uint16 a;
    //cin >> hex >> a;
    scanf_s("%hd", &a);//16进制的两种输入方式

    字符串循环左|右移实现(C/C++)

    字符串循环右移K位

    (1)图解思考

    (2)代码实现

    时间复杂度O(n) | 空间复杂度O(1)

    // 三次翻转实现
    #include <iostream>
    #include <cstring>
    
    void reverse(char str[],int start,int end){
        for( ;start < end; start++,end--){
            char tmp = str[start];
            str[start] = str[end];
            str[end] = tmp;
            // start++;
            // end--;
        }
    }
    
    void rotateStrRight(char str[], int offset,int len){
            if(str == nullptr || len == 0){
                return;
            }
            offset = offset % len;
            // 三次翻转
            reverse(str, 0, len-offset-1);
            reverse(str, len-offset, len-1);
            reverse(str, 0, len-1);
    }
    
    int main(){
        int  steps = 2;
        char str[] = "12ab";
        int  len = strlen(str);
        //printf("len = %d\n",len);
        printf("移动前: %s\n", str);
        rotateStrRight(str,steps,len);
        printf("移动后:%s\n", str);
    }

    字符串循环左移K位

    (1)说明

     # 字符串循环左移
    
    (1)左移与右移同理,只是划分段的方向相反,交换区间自然有区别
    (2)例如:1234ab,循环左移4位(从左划分)
    (3)1234|ab -> 4321|ab -> 4321|ba -> ab1234
    (4)例如:1234ab,循环右移4位
    (5)12|34ab -> 21|34ab -> 21|ba43 -> 34ab12

    (2)代码实现

    // 三次翻转实现
    #include <iostream>
    #include <cstring>
    
    void reverse(char str[],int start,int end){
        for( ;start < end; start++,end--){
            char tmp = str[start];
            str[start] = str[end];
            str[end] = tmp;
        }
    }
    
    void rotateStrLeft(char str[], int offset,int len){
        if(str == nullptr || len == 0){
            return;
        }
        offset = offset % len;
        // 三次翻转
        reverse(str, 0, offset-1);
        reverse(str, offset, len-1);
        reverse(str, 0, len-1);
    }
    
    int main(){
        int  steps = 3;
        char str[] = "1234ab"; // 4ab123
        int  len = strlen(str);
        //printf("len = %d\n",len);
        printf("移动前: %s\n", str);
        rotateStrLeft(str,steps,len);
        printf("移动后:%s\n", str);
    }

    循环左右移结果相同条件

    (1)str.length>

    (2)测试结果(8/2 = 4)

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持易采站长站。