用递归实现简单的进制转化器(模块化设计):学习递归题型之一

引言:

                在阅读C Primer Plus时,我发现一个非常有意思的将十进制转化二进制的方法,我通过逻辑推理,将十进制转化为八进制以及十六进制的方法类比了出来;在此处呢,我将用递归实现对十进制转化为三种其它进制,实现情况这样的:

    

 具体情况就是这样,虽然很简单但是我这里其实是强化递归的学习和模块化的概念强化;

在看了我的实现的方法和思路的话,大家可以根据兴趣去实现十六进制转化其他进制,八进制转化其他进制(可以转化为十进制,再转化,虽然看上去这个算法很low),你也可以去做一个界面,做个简单的进制转化计算器,在开始让使用者选择输入的进制以及转化为什么进制等等,就到这里了,不吹水了,接下我们来对进制转化的实现;

实现:

        1.主体程序main:

                 首先,我们要明确输入的是什么,因为是简单的进制转化,选择的输入的是无符号的数(也就是unsigned int n);ok,先不谈怎么具体实现对进制转化的实现;我们先来把主体程序搭起来,出现什么问题后再加其他代码来解决问题:

#include <stdio.h>
int main()
{
	unsigned int n;
	void Binary(unsigned int n);
	void Octonary(unsigned int n);
	void Hexadecimal(unsigned int n);
	printf("请输入你需要转化的十进制数:");
	scanf_s("%d", &n);
	printf("%d的二进制数为:", n);
	Binary(n);
	printf("\n%d的八进制数为:", n);
	Octonary(n);
	printf("\n%d的十六进制是:", n);
	Hexadecimal(n);
	return 0;
}

ok,主体搭起来了;接下来分别实现:

        2.十进制转化二进制:

                首先,我们来了解具体的算法实现;

                对于十进制转化二进制来说,我们对于奇数的十进制,它的二进制最后一位总是 1 ,反          过来看,对于偶数的十进制,它的最后一位总是 0,在了解到这个特点后(通过n % 2实                  现);我们只要将十进制对应二进制的 最后一位求出来后,将十进制相对于二进制后退一              位,然后再求;

                对于十进制后退一位的方式就是除以转化的的进制,这里的转化就是 n  /  2;就行了,            至于为什么呢,因为(以25为例子):25 = 1 * 2^5 + 1 * 2^3 +  0 * 2^2 + 0 * 2^1 + 1 * 2^0;

        可以清晰地发现,每次除以2后,最后一个式子都可以算作是变少了一位,将小数点左移一位,同时又因为n 是int就像是去掉了一位;

        同时因为我们最先把最后一位最先求出来,在递归实现的时候,就应该把他放在后面输出;

就是放在递归的后面;

        OK  来实现:

void Binary(unsigned int n)
{
	if (n == 1)
	{
		printf("1");
		return;
	}
	if (n % 2)
	{
		Binary(n / 2);
		printf("1");
	}
	else
	{
		Binary(n / 2);
		printf("0");
	}
}

ok  具体是实现就是这样,但是我在书上看到了一个更加凝练的实现:

void Binary(unsigned int n)
{
	int b = n % 2;
	if (n > 2)
		Binary(n / 2);
	putchar(b == 0 ? '0' : '1');
	return;
}

采用putchar输出,挺有意思,你也可以采用printf都可以,但是我发现这个求10000时会出现少了最高位的情况,不过这个胜在简洁;

        2.然后就是十进制转化为八进制:

                   具体实现的思想就跟上面差不多;实现:

void Octonary(unsigned int n)
{
	int o = n % 8;
	if (n > 8)
		Octonary(n / 8);
	printf("%d", o);
	return;
}

同样也有两种写法:

void Octonary(unsigned int n)
{
	if (n < 8)
	{
		printf("%d", n);
		return;
    }
	if (n >= 8)
	{
		Octonary(n / 8);
		printf("%d", n % 8);
	}
}   

        3.十进制转化为十六进制:

        首先我们发现十六进制的输出是完全不一样的,有着  a  b c d e f的输出;

        首先定义的是一个全局变量:因为后面的实现转化十六进制的函数都会用的

#include <stdio.h>
int i = 0;
int h[100];
int main()

        因此我们要选择去对具体数值的选择输出,我在这里采用了一个数组是遍历循环去选择输出;检测的方式就是选择去对一个  -1的确认:因此我初始化为了一个全是-1的数组;这里我将初始化也做成了一个模块:

void ini_h(void)
{
	for (i = 0; i < 100; i++)
		h[i] = -1;
	i = 0;
}

这里将i  = 0是为什么呢;因为在后面的递归实现需要使用到i,总不能在递归函数里面实现,因为每次调用递归都要进行一次函数,同时因为i 是全局变量而且我们用数组保存取出来的函数,里面的i要进行变化;文字,可能看不明白,我们来实现:

void Hexadecimal(unsigned int n)
{
	int g = n % 16;
	if (n > 16)
	{
		Hexadecimal(n / 16);
		i++;
	}
	h[i] = g;
	return;
}

ok   实现完成;

接下来选择输出:

        首先我们这里可以选择Switch来进行对应输出,同时我们需要知道输出多少个数才结束;

所以在输出之前要遍历循环找到== -1;的数组下标,接下来实现:

void put_h(void)
{
	int count;
	for (i = 0; h[i] != -1; i++)
		if (h[i] == -1)
			break;
	count = i;
	for (i = 0; i < count;)
	{
			switch (h[i])
			{
			case 10:printf("A"), i++; break;
			case 11:printf("B"), i++; break;
			case 12:printf("C"), i++; break;
			case 13:printf("D"), i++; break;
			case 14:printf("E"), i++; break;
			case 15:printf("F"), i++; break;
			default:printf("%d", h[i]), i++; break;
			}
	}
}

OK  全部的函数都已经实现:

我们来拼接;

        4.最终程序:

#include <stdio.h>
int i = 0;
int h[100];
int main()
{
	unsigned int n;
	void ini_h(void);
	void put_h(void);
	void Binary(unsigned int n);
	void Octonary(unsigned int n);
	void Hexadecimal(unsigned int n);
	printf("请输入你需要转化的十进制数:");
	scanf_s("%d", &n);
	printf("%d的二进制数为:", n);
	Binary(n);
	printf("\n%d的八进制数为:", n);
	Octonary(n);
	printf("\n%d的十六进制是:", n);
	ini_h();
	Hexadecimal(n);
	put_h();
	return 0;
}
void Binary(unsigned int n)
{
	if (n == 1)
	{
		printf("1");
		return;
	}
	if (n % 2)
	{
		Binary(n / 2);
		printf("1");
	}
	else
	{
		Binary(n / 2);
		printf("0");
	}
}
//void Binary(unsigned int n)
//{
//	int b = n % 2;
//	if (n > 2)
//		Binary(n / 2);
//	putchar(b == 0 ? '0' : '1');
//	return;
//}
//void Octonary(unsigned int n)
//{
//	if (n < 8)
//	{
//		printf("%d", n);
//		return;
//    }
//	if (n >= 8)
//	{
//		Octonary(n / 8);
//		printf("%d", n % 8);
//	}
//}   
void Octonary(unsigned int n)
{
	int o = n % 8;
	if (n > 8)
		Octonary(n / 8);
	printf("%d", o);
	return;
}
void ini_h(void)
{
	for (i = 0; i < 100; i++)
		h[i] = -1;
	i = 0;
}
void Hexadecimal(unsigned int n)
{
	int g = n % 16;
	if (n > 16)
	{
		Hexadecimal(n / 16);
		i++;
	}
	h[i] = g;
	return;
}
void put_h(void)
{
	int count;
	for (i = 0; h[i] != -1; i++)
		if (h[i] == -1)
			break;
	count = i;
	for (i = 0; i < count;)
	{
			switch (h[i])
			{
			case 10:printf("A"), i++; break;
			case 11:printf("B"), i++; break;
			case 12:printf("C"), i++; break;
			case 13:printf("D"), i++; break;
			case 14:printf("E"), i++; break;
			case 15:printf("F"), i++; break;
			default:printf("%d", h[i]), i++; break;
			}
	}
}

##ok,到这里分享结束了,如果大家觉得喜欢的话,点个赞,加个收藏,这对我很有帮助,谢谢;

##如果有问题的话,欢迎纠正;

点赞收藏!!!!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值