• 20135202闫佳歆-第二章家庭作业-2.69


    第二章家庭作业

    选题:2.69

    分值:三分

    作业过程:

    以下是rotate_right函数的代码:

    unsigned rotate_right(unsigned x, int n)
    {
    	int endbit;
    	int i;
    	if(n==0)
    		return x;
    	else
    	{
    		for(i=0;i<n;i++)
    		{
    			endbit = x & 0x1;
    			endbit = endbit << (8*sizeof(unsigned)-1);
    			x = x >> 1;
    			x = x | endbit;
    		}
    	}
    	return x;
    }
    

    这里用到的原理是,区分n的情况,如果是0则直接返回原值,如果不是0,就按照移位的次数控制循环,每次循环只移位1位。

    具体循环的实现,是借助了一个变量为endbit,最后一位,用来保留右移一位后损失掉的那位,再通过移位使这位变成最高位,最后与x移位后的数据进行或运算,这样就完成了循环右移一次的功能;共需循环右移几次,就重复几次这个循环。

    完成的代码如下:

    #include <stdio.h>
    
    unsigned rotate_right(unsigned x, int n);
    
    int main()
    {
    	int n = 0;
    	unsigned x;
    	int w = sizeof(unsigned)*8;
    	int flag = 0;
    	unsigned result;
    
    	while(!flag)
    	{
    		printf("please input how many bits you want to rotate_right shift:
    ");
    		scanf("%d",&n);
    		if (n < 0 || n >= w)
    		{
    			printf("Wrong! Please input again!
    ");
    		}
    		else
    			flag = 1;
    	}
    
    printf("please input your data:
    0x");
    	scanf("%x",&x);
    
    	result = rotate_right(x,n);
    	printf("the result is:0x%x
    ",result);
    
    	return 0;
    }
    
    unsigned rotate_right(unsigned x, int n)
    {
    	int endbit;
    	int i;
    	if(n==0)
    		return x;
    	else
    	{
    		for(i=0;i<n;i++)
    		{
    			endbit = x & 0x1;
    			endbit = endbit << (8*sizeof(unsigned)-1);
    			x = x >> 1;
    			x = x | endbit;
    		}
    	}
    	return x;
    }
    

    实验运行结果如下:

    实验中遇到的问题:

    这个函数原型的构造并不难,找到思路后困扰我一时的只是是用或还是与,这个很容易就能够解决,更大的问题在我的主函数中输入无论如何都得不到正确的结果,后来发现是因为我的输入是0x12345678,我以为这个可以直接转换为16进制但是不可以,输出也是十进制,所以这导致了我的结果错误百出,后来我通过百度发现了%x的方法,输入输出格式改为这个之后就可以方便的输入输出16进制,并且在输入之前加了提示语0x,就可以得出正确的结果了。

    这道题本身难度不算大,我主要还是栽在了自己的粗心上,没有注意输入输出格式,只想当然的去做,吸取了这次教训,以后的作业就不会有那么多冤枉路了。

    代码的优化

    从每次右移一位,按循环次数控制右移位数,能不能扩展成一步到位移动n位呢?我把代码变成了以下样子:

    unsigned rotate_right(unsigned x, int n)
    {
    	int endbit;
    	int i;
    	if(n==0)
    		return x;
    	else
        {
    	    endbit = x << (8*sizeof(unsigned)-n);
    	    x = x >> n;
    	    x = x | endbit;
        }
    	return x;
    }
    

    这样就可以直接移动n位了。

    这里还有一个小插曲,关于开始的左移位数是要-n还是-什么,是右移了n位,上面的左移就要减n。

    然后我又想,n=0的情况能不能并进去?代码就变成了这样子:

    unsigned rotate_right(unsigned x, int n)
    {
    	int endbit;
    
        endbit = x << (8*sizeof(unsigned)-n);
        x = x >> n;
        x = x | endbit;
    
    	return x;
    }
    

    验证是可以的。

    endbit作为一个中间值,是不是有点多余?去掉之后变成:

    unsigned rotate_right(unsigned x, int n)
    {
        x = (x >> n) | x << (8*sizeof(unsigned)-n);
    
    	return x;
    }
    

    也是可以的,更简洁了。

    那么可以干脆直接用return返回:

    unsigned rotate_right(unsigned x, int n)
    {
        return (x >> n) | x << (8*sizeof(unsigned)-n);
    }
    

    这个一步步简化代码的过程让我做完了之后十分满意,最开始的想法很简单,但是代码实现却很复杂,通过一步步的简化最终使代码变的简洁好看,成就感很大。但是对于我现在的水平,如果直接给我这样的一个代码,阅读起来还是有些费劲的,需要多加练习。

  • 相关阅读:
    小程序数据库 用正则查询字符串字段/数组字段
    一键禁用Windows多余?服务
    Switch 10.1.0 无法启动软件请在home菜单中再试一次 解决方法
    算法记录
    LeetCode——面试题 10.01. 合并排序的数组
    LeetCode——98. 验证二叉搜索树
    LeetCode——55. 跳跃游戏
    LeetCode——92. 反转链表 II
    LeetCode——206. 反转链表
    LeetCode——225. 用队列实现栈
  • 原文地址:https://www.cnblogs.com/20135202yjx/p/4895154.html
Copyright © 2020-2023  润新知