题目:开发一个程序,编写一个函数,输入1~32767之间的整数,并把这个整数显示为一些列数字,每组数字都是用两个空格分开。例如,整数4562应该显示为:
4 5 6 2
华罗庚曾经说过,研究一个问题要从简单的入手,然后再从简单的向复杂问题入手。于是我就用一个特殊的例子下手,比如用1234这个数,最后输出的结果应该是1 2 3 4。怎么才能得到这个结果呢?使用除法的商和余数可以得到正确的结果。如下表
次数 被除数 除数 商 余数
1 1234 / 1000 = 1......234
2 234 / 100 = 2...... 34
3 34 / 10 = 3...... 4
4 4 / 1 = 4...... 0
可以看到前一次的余数作为了下一次的被除数,而商就是我们要输出的部分。于是可以得到算法:
1.被除数为1234,除数为1000;
2.输出被除数/除数的商和两个空格;
3.把被除数/除数的余数给被除数;
4.把除数/10的商给除数;
5.重复步骤2和步骤4,直到被除数为0;
非常荒唐的是,我的算法只能用于这个特殊的例子。以上的被除数是四位数所以我们才除以1000,如果是五位数我们就应该除以10000,三位数除以100,两位数除以10,1位数除以1。规律是除以10的n-1次方(n是用户输入整数的位数)但是如何确定用户输入的是位数呢?问题现在又转移到求位数上来了。这次还用1234这个整数作为切入的例子。1234是四位数,如何确定?
可以使用一个循环和一个计数器。
1234每次除以10,再将所得的商赋值给新的被除数。计数器记录循环的次数(每次循环自身累加1)
这样1234/10=123, 123/10=12, 12/10=1, 1/10=0, 直到商为零的时候循环结束,一共除了4次,这个4就是位数。
这是通用的。如果是五位数那么会除以5次,5就是位数,其他的位数是同样的道理。
返回到我的那个荒唐的算法中,让我们修改一下。
1. 求得用户输入数字(被除数)的位数;
2. 输出 被除数 / 10的[位数-1]次方的商和两个空格;
3. 步骤二中的余数作为被除数;
4. 把位数-1的值给位数;
5. 重复步骤2到步骤4,直到位数为0
以下是我编写的代码:
2 #include < math.h >
3
4 void divideNumber( int number );
5
6 main()
7 {
8 int num;
9 printf( " Enter a integer: " );
10 scanf( " %d " , & num );
11 divideNumber( num );
12
13 return 0 ;
14 }
15
16 /**/ /* show the divided numbers */
17 void divideNumber( int number ) {
18 int counter = 1 ; // record the digits.
19 int temp;
20
21 // How many digit in number?
22 temp = number;
23 while ( temp / 10 )
24 {
25 temp /= 10 ;
26 counter ++ ;
27 } // counter has recorded the digits.
28
29 while ( counter )
30 {
31 printf( " %d " , number / ( int )pow( 10 , counter - 1 ) );
32 number %= ( int )pow( 10 , counter - 1 );
33 counter -- ;
34 }
35 printf( " \n " );
36 }
后记:今天一个同学的同学想让我帮忙看看他编写的连连看程序有什么问题,给我的只有一大堆代码。这让我无从下手,我想看的是他的设计思想和算法,我认为这比代码要重要的多。因为在我看来如果有了设计思想和算法,任何编程语言就都无所谓了(就是说哪一种语言都可以编写出来)。这虽然是一道小题,但是我还是想强调一下设计思想和算法的重要性。