2.4 进制转换

                   2.4  进制转换

日常生活中我们计数的方式有很多,如一年有12个月,则是十二进制,一周有七天,则是七进制,等等。平常我们用的最多的最习惯的十进制,是古人留下来的财富。需要强调的是任何一个值都可以用任何一种进制描述,但它的值是不变的,正如我们今天在一周中可以描述为星期几,在一个月中描述为多少号一样。

使用R进制计数的规则:

只使用R个基数:012,···,R-1

R进一,退一当R进行数的运算。

2.4.1  R进制数转化为十进制数

这个转化问题较简单,根据上面讲的R进制的计数规则进行展开就得到相应的十进制数的表示方法。

anan-1···a1a0.a-1a-2···a-m)

=an*Rn+an-1*Rn-1+···+a1*R1+a0*R0+a-2*R-2+···+a-m*R-m

= ai*Ri。

2.4.2 十进制数转化为R进制数

由于十进制数的整数与小数转化为R进制的方法不同,所以必须分开讨论。先看十进制整数的转化,再讨论十进制小数的转化,最后讨论R进制的计数及转化问题。

1. 进制整数的转化

通过具体实例进行分析,如对十进制数325转化,根据原理可

按下式这样假设:

32510=3*102+2*101+5*100 

=(anan-1…a1a0)R

an*Rn+an-1*Rn-1++a1*R1+a0*R0

=(an*Rn-1+an-1*Rn-2++a1)*R+a0      

两边同时除以R,得到整数部分和整数部分相等,余数和余数相等,显然右边的余数就是a0,再进行同样的处理就得到a1,一直这样进行下去,直到左边的数为0时为止,由于先求出的是R进制的最低位,再按求解过程倒过来写出就得到相应的R进制数。

R6为例,(32510=(13016,转化过程详见图21所示。

十进制数转化为R进制数,得到整数部分的转换规律就是“除R取余,反序输出”。

2. 十进制小数的转化

通过具体实例进行分析,如对十进制数0.325转化,根据原理

以这样假设:

          (0.37510=3*10-1+7*10-2+5*10-3

=(0.a-1a-2…a-m)R

a-1*R-1+a-2*R-2++a-m*R-m

=(a-1+a-2*R-1++a-m*R-m+1)*R-1

两边同时乘以R,等式两边的整数部分和小数部分分别相等,显然右边的整数部分就是a-1,再去掉等式的整数部分,然后进行相同的处理,就求得了a-2,一直进行下去,直到左边的值为0时或到要求的精度为止,这样就将十进制小数转化为相应的R进制数了。

 

 

 

 

R2为例,(0.37510=(0.0112,求解过程详见图22所示,这样就将十进制小数转化为相应的R进制数,得到小数部分的转换规律就是“乘R取整,顺序输出”。

3.进制数转化-R进制数

 大家对R进制数都已经很熟悉了,但是,还有一种-R进制数。任何一个整数n都可以表示成n,其中∈〔0,R1〕,是整数。并且>=0

 现在我们来讨论R进制数怎么转化为-R进制数。需不需要先将R进制数转化为十进制数,

再将相应的十进制数利用上面的转化归律化为-R进制数,当然这是一种方法,但我们完全可以不必这么做。不妨以一个具体实例来讨论转化规律,如:

         =4*63+3*62+2*61+5*60。

 将等式右边改写成一个-6进制数的形式:

         4*(-63+3*(-62+2*(-61+5*(-6)0。

 比较观察一下,发现偶次幂的项与6进制数的相等,差别出在奇次幂的项,怎样修改才使它满足-6进制数表示的形式呢?记住我们计算的原理:进制只是表示方式不同,值是不变的

      那么对于上面我们倒数第二项:2*61=X*(-61,而基数X是一个05之间的数,显然是不能成立的,要相信,X只能等于-2,而-2不能作为-6进制数的基数,解决这个问题就向高位借一个1,这样X变为(6.-2),由于高位已经是相等的,所以高位的基数相应要加1。若高位基数加1后,值已超过5,则修改幂。这样就能确保值没有变。

2.4.3 应用举例

在信息学奥赛中,巧妙地使用某些数制的特点,可能使解题变得相当简单。请看下面几道例题。

15 火车转轨问题。

2-3中两条轨道连接到一个铁路转轨处,形成一个铁路转轨网络的栈。其中右边轨道为输入端。如果执行了Push,Push,Pop,Push,Push,Pop,Pop,Pop,就会将输入端的车皮编号顺序1,2,3,4变成2,4,3,1,请编程求左边车皮编号为1,2,3,4时,在右边轨道可能得到的所有车皮编号顺序。

 

 

 

 

 

 

 

 

【算法分析】

这个例子是典型的栈应用题。但如果单纯使用栈技术,则在不断的判定入栈出栈过程中,很容易迷失方向。现在让我们仔细分析,看看有没有其他方法可以解决此题:①四列车必须经过转轨才能到达轨道的另一端,且进栈出栈各一次;②如果以1代表进栈,0代表出栈,则火车转轨可以用一相二进制数来表示,如,10代表火车进栈后出栈,01代表火车出栈后进栈;③四列火车都到达转轨的另一侧,一共进出栈八次,恰好一个字节8个位;④由于必须先进栈才能出栈,故在二进制的每一位数前,1的个数总不少于0的个数,否则转轨内无车可出。这样就巧妙地利用数的进制将原问题转化为一个求0255内的二进制数中符合相应条件的数的个数。

【参考程序】

 CONST n=4;                                {火车轨程序}

 VAR 

   a,b,c:array[1..n] of integer;

   top,I:integer;

 FUNCTION judge(m:integer):Boolean;         {判断二进制数m是否满足条件④}

   VAR

S0,s1:integer;                            {s00的个数,s11的个数}

 I:integer;

BEGIN

   Judge:=true;

   S0:=0;

S1:=0;

FOR I:=1 to 2*n do                  

  BEGIN                                  {从后往前计算01的个数}

    IF m mod 2 =0 THEN s0:=s0+1 ELSE s1:=s1+1;

     M:=m div 2;

    If s0<s1 THEN BEGIN                    {如果0的个数比1的个数少,则不满足条件}

              Judge:=false;

               Exit;

               End{THEN}

   END;{FOR};

IF s0<>s1 THEN BEGIN                      {如果整个数的01的个数不相等,也不满足条件}

              Judge:=false;

              Exit;

            END{THEN}

    END{judge}

 PROCEDURE push;                          {进栈}

  VAR I:integer;

   BEGIN

     B[top]:=a[1];

     Top:=top+1;

      FOR I:=1 to n-1 DO a[I]:=a[I+1];

      A[n]:=0;

      Write(‘push’);

    END;{push};

 PROCEDURE pop;                          {出栈}

   VAR I:integer;

  BEGIN 

    Top:=top-1;

     FOR I:=1 to n-1 DO c[I]:=c[I+1];

      C[n]:=b[top];

      Write(’POP’);

   END;

 PROCEDURE print(m:integer);          {输出满足条件的情况}

    VAR

      T:array[1..2*n] of bollean;

       I:integer;

   BEGIN

      Write(m,‘  ‘);

      FOR I:=1 TO N DO A[I]:=I;

      FOR I:=1 to 2*n DO 

        BEGIN

          T[I]:=(m mod 2=0)

          M:=m div 2;

      END;{FOR};

FOR I:=2*n  DOWNTO 1DO 

       IF t[I] THEN pop ELSE push;

    FOR  I:=I to DO write(c[I]);

     Writeln;

   END;

  BEGIN                            {主程序}

       Top:=1;

       FOR I:=1 to 255 DO            {8个位,最多为255}

         IF judge(i) THEN print(i);

       Writeln;

   END. 

      

  

        

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2010-10-11 21:21  lj_cherish  阅读(636)  评论(0编辑  收藏  举报