十进制数转化为2、8、16进制

题目1:将非负十进制整数n转换成b进制。(其中b=2~16)

1、题目分析
该问题的主要点在于对整数n进行取模运算,得到余数,同时将n除2,进行递归。
2、递归程序设计思路
递归模型
该递归程序要求将十进制数n转换为二进制数,在这个转换过程中需要对n进行取模,得到余数,同时对n进行除2操作得到下一个要取模的数。因此需要将整数n作为参数,不断的进行取模运算。同理十进制转换为八进制、十进制转换为十六进制也都是进行相应的取模以及除运算。

在这里插入图片描述
程序设计

class Transform:
    """进制转换类,将三个方法封装在类中"""
    def transform_2(self, n, list_arr=[0]):
        """
        二进制转换递归方法,将十进制数转换为二进制
        :param n: 传入的十进制数
        :param list_arr: 辅助列表,将取模得到的余数放入列表
        :return: 返回取余结果的列表
        """
        if n != 0:  # 函数的递归体
            list_arr.append(n % 2)
            return self.transform_2(n//2, list_arr)  # 递归调用函数
        else:  # 递归的结束条件
            return list_arr[::-1]

    def transform_8(self, n, list_arr=[0]):
        """八进制转换递归方法,将十进制数转换为八进制"""
        if n != 0:
            list_arr.append(n % 8)
            return self.transform_8(n // 8, list_arr)
        else:
            return list_arr[::-1]

    def transform_16(self, n, list_arr=[0]):
        """十六进制转换递归方法,将十进制数转换为十六进制"""
        if n != 0:
            list_arr.append(n % 16)
            return self.transform_16(n // 16, list_arr)
        else:  # 将十六进制中大于10的部分用特定的字符表示
            for i in range(len(list_arr)):
                if list_arr[i] == 10:
                    list_arr[i] = 'A'
                elif list_arr[i] == 11:
                    list_arr[i] = 'B'
                elif list_arr[i] == 12:
                    list_arr[i] = 'C'
                elif list_arr[i] == 13:
                    list_arr[i] = 'D'
                elif list_arr[i] == 14:
                    list_arr[i] = 'E'
                elif list_arr[i] == 15:
                    list_arr[i] = 'F'
            return list_arr[::-1]

3、递归树
十进制数转化为2、8、16进制_第1张图片
4、非递归方法
非递归方法与递归方法的实现步骤类似,不同的地方是非递归方法是通过循环实现的。

class Transform:
    """进制转换类,将三个方法封装在类中"""
    def transform_2(self, n, list_arr=[0]):
        """
        二进制转换非递归方法,将十进制数转换为二进制
        :param n: 传入的十进制数
        :param list_arr: 辅助列表,将取模得到的余数放入列表
        :return: 返回取余结果的列表
        """
        while n != 0:
                list_arr.append(n % 2)
                n = n // 2
        return list_arr[::-1]

    def transform_8(self, n, list_arr=[0]):
        """八进制转换非递归方法,将十进制数转换为八进制"""
        while n != 0:
            list_arr.append(n % 8)
            n = n // 8
        return list_arr[::-1]

    def transform_16(self, n, list_arr=[0]):
        """十六进制转换非递归方法,将十进制数转换为十六进制"""
        while n != 0:
            list_arr.append(n % 16)
            n = n // 16
        for i in range(len(list_arr)):  # 将十六进制中大于10的部分用特定的字符表示
            if list_arr[i] == 10:
                list_arr[i] = 'A'
            elif list_arr[i] == 11:
                list_arr[i] = 'B'
            elif list_arr[i] == 12:
                list_arr[i] = 'C'
            elif list_arr[i] == 13:
                list_arr[i] = 'D'
            elif list_arr[i] == 14:
                list_arr[i] = 'E'
            elif list_arr[i] == 15:
                list_arr[i] = 'F'
        return list_arr[::-1]

5、代码测试
将十进制数1024传入,分别进行2,8,16进制转换的测试。
二进制
十进制数转化为2、8、16进制_第2张图片
八进制
十进制数转化为2、8、16进制_第3张图片
十六进制
十进制数转化为2、8、16进制_第4张图片
自定义异常处理机制的测试
十进制数转化为2、8、16进制_第5张图片
题目2:
任何一个正整数都可以用2的幂次方表示。
137=27+23+2^0    
同时约定幂次方用括号来表示,即ab 可表示为a(b)。
   由此可知,137可表示为:
     2(7)+2(3)+2(0)
进一步:7= 22+2+20 (21用2表示)
     3=2+2^0
所以最后137可表示为:
     2(2(2)+2+2(0))+2(2+2(0))+2(0)
   又如:
     1315=2^10 +2^8 +2^5 +2+2^0
所以1315最后可表示为:
   2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
  输入:正整数(n≤20000)
输出:符合约定的n的0,2表示(在表示中不能有空格)
输入格式 Input Format
一个正整数
输出格式 Output Format
符合约定的n的0,2表示(在表示中不能有空格)
样例输入 Sample Input
73
样例输出 Sample Output
2(2(2)+2)+2(2+2(0))+2(0)

1、题目分析:该题的关键点在于如何记录递归的次数,以及对递归次数的再次递归,最终实现全部由2和0表示的一个整数。
2、递归模型
该递归最终是将一个正整数全部分解成由2和0表示的表达式,因此该正整数需要进行除2递归,直至达到1,此时再对递归深度进行判断,总共有三种情况,递归深度分别为0,1,2,默认当递归次数大于2时对递归深度再次进行递归,将递归深度的次数也用用0和2表示。
十进制数转化为2、8、16进制_第6张图片
3、算法设计思路
该程序首先对正整数进行,递归运算,然后在对递归深度进行递归,最后对中间过程的数进行奇偶性判断,再按照包含2和0的指定格式输出。

//n为操作数,deep为递归深度
void number_operation(int n, int deep)
{
    if (1 == n) //递归结束条件
    {
        //将deep用0和2表示
        switch(deep)
        {
        case 0:cout<<"2(0)";break;
        case 1:cout<<"2";break;
        case 2:cout<<"2(2)";break;
        default:
            cout<<"2(";
            number_operation(deep,0);
            cout<<")";
        }
    }
    else    
    {
        //n除以2,递归深度加1
        number_operation(n/2, deep+1);//递归体
        //如果模2有余数,则为2^deep
        if (1 == n%2)
        {
            //将deep用0和2表示
            switch(deep)
            {
            case 0:cout<<"+2(0)";break;
            case 1:cout<<"+2";break;
            case 2:cout<<"+2(2)";break;
            default:
                cout<<"+2(";
                number_operation(deep,0);
                cout<<")";
            }
        }
    }
}

4、调试及测试
输入1024,对该过程进行测试,刚开始递归深度为0

十进制数转化为2、8、16进制_第7张图片
当递归十次,即递归深度的次数为10,n变为1,然后对递归深度再次进行递归。

十进制数转化为2、8、16进制_第8张图片
当对递归深度进行递归时,传入的参数为上层递归得到递归深度,即为10,同时将递归深度置为0,重新开始计数。

十进制数转化为2、8、16进制_第9张图片

最后得到最终结果,结果表示正确,说明该程序可以正确运行。
在这里插入图片描述
5、总结
通过这次对十进制数转换为2进制和将任意一个正整数使用0和2表示的递归程序的练习,不仅学到了关于递归的更多方法,而且总结得到了关于递归更深的认识。学会了使用递归树表示递归程序,递归程序可以大大减少平时使用循环进行运算的工作量,同时递归程序在运行过程也很容易出错,往往出现在对参数的设置中,调试起来也是比较麻烦,但总的来说通过递归可以更方便的处理一些较复杂的难题,如汉诺塔问题、八皇后问题,这些都不是可以简单的通过循环可以实现的。因此,想要熟练的使用递归,还需要在学习中对递归多加练习。

你可能感兴趣的:(作业,递归,进制转换)