教材《Visual C# 2010从入门到精通》(John Sharp著,周靖译)在P115提到的将十进制数转换成八进制的算法如下:
int amount = int.Parse(number.Text); // 获取文本框控件中输入的十进制数
steps.Text = ""; // 显示结果的文本框清空
string current = ""; // 存放转换结果的字符串,初始值为空串
do
{
int nextDigit = amount % 8; // 取amount除8的余数
amount /= 8; // 为下一次作准备,amout缩小8倍
int digitCode = '0' + nextDigit; // (1)获取余数对应数字的字符编码
char digit = Convert.ToChar(digitCode); // (2)将字符编码转换成字符型
current = digit + current; // (3)将余数的字符编码添加至结果字符串的前面
steps.Text += current + "\n"; // 将这步转换结果输出
}while (amount != 0);
上课时,我们曾经讨论过,上述的(1)(2)(3)可以用下面这一句代替:
current = nextDigit + current;
由于整型变量nextDigit与字符串变量current相加,实际上相当于current= nextDigit.ToString() + current
我们上机调试过,上述程序能够正确将一个int范围内的整数转换成八进制数,并将每步转换的结果逐次在结果文本框中显示。
由于每一步除八的余数必须在0-7之间,直接可以转换成对应的字符'0'-'7'。上述程序可以轻松做到这一点。
现在我们需要将十进制数转换成十六进制,那么,每一步除16的余数是在0-15之间,它需要用字符'0'-'9','A','B’,'C','D','E','F'等16个符号来表示。
有的同学已经想到了,用if语句或switch语句来处理,来实现上述编码的转换,对应的程序如下:
int amount = int.Parse(number.Text);
steps.Text = "";
string current = "";
do
{
int nextDigit = amount % 16;
amount /= 16;
string code = ""; // code用以存储每一位对应的编码
switch (nextDigit)
{
case 10:
code = "A";break;
case 11:
code = "B"; break;
case 12:
code = "C"; break;
case 13:
code = "D"; break;
case 14:
code = "E"; break;
case 15:
code = "F"; break;
default: // 不满足10-15,必然是在0-9之间
code = nextDigit.ToString();
break;
}
current = code + current;
steps.Text += current + "\n";
} while (amount != 0);
经过调试,上述程序可以做到将十进制整数转换成对应的十六进制数,并逐步输出。
但上述使用switch语句进行转换的方法稍显烦琐,会造成代码过于臃肿,且可读性不太高。这种代码转换常用“查表转换法”。
所谓“查表转换法”,就是先将码表顺序存放在一个线性表或数组中,然后通过下标或索引快速找到某个数据所对应的编码。这种方法可以大大提高编码转换或者计算的效率,在算法实现中经常用到。
比如,我们可以将16进制用到的16个编码,先存放到一个名为codes的字符串变量中:
string codes = "0123456789ABCDEF";
之后,我们就可以通过求这个字符串字串(Substring)的方法,取某个数对应的编码。如:11对应的编码,就是上述字符串第11个位置(从0开始)的字符,即字符 B。
current = codes.Substring(nextDigit, 1) + current;
最后,完成的代码如下:
int amount = int.Parse(number.Text);
steps.Text = "";
string current = "";
string codes = "0123456789ABCDEF"; // 设置16进制转换编码表
do
{
int nextDigit = amount % 16;
amount /= 16;
current = codes.Substring(nextDigit, 1) + current; // 查表转换
steps.Text += current + "\n";
} while (amount != 0);
思考:请你写一个方法Conversion,它接收两个参数,一个是将转换到其它进制的整数number,一个是转换的进制system(取值2-36之间)。该方法返回整数number在进制system下对应的数据的字符串表示形式,如:Conversion(123456,12)= "5B540"。