18.12.09-C語言練習:黑洞數 / Kaprekar問題
題目:
程式:
1 #include <stdio.h> 2 3 int main(void) { 4 int n, a, b, c, t, A, B; 5 printf("輸入一個三位數整數:"); 6 scanf("%d",&n); 7 do{ 8 /*a, b, c 分別是百位數,十位數,個位數*/ 9 a = n/100; 10 b = (n%100)/10; 11 c = (n%10); 12 /* 百位數,十位數,個位數按照從大到小的順序重排,以便下一步中求重排後的最大值A和最小值B*/ 13 if(a<b) { 14 t = a; a = b; b = t; 15 } 16 if(a<c) { 17 t = a; a = c; c = t; 18 } 19 if(b<c) { 20 t = b; b = c; c = t; 21 } 22 /*從排後的最大數A與最小數B*/ 23 A = a * 100 + b * 10 + c; 24 B = c * 100+ b * 10 + a; 25 /*將最大數與最小數的差,重新賦給變數n,以便做迴圈判斷或下次迴圈使用*/ 26 n = A - B; 27 /*輸出過程*/ 28 printf("%d - %d = %d\n", A, B, n); 29 } while(n!=495 && n!=0); 30 return 0; 31 }
程式說明:
1. 程式大體思路可以看程式中註釋,大體分為兩個步驟:輸入和迴圈中計算。其中迴圈中計算過程分為這麼幾個步驟:求個位十位百位上三個數字;個位十位百位三個數字按從大到小排列;求得重排後的最大值和最小值;求差和輸出。
2. 難點在於:(1)求個位十位百位數字;(2)確定迴圈變數n;(3)黑洞數演算法計算過程的程式表達。
3. 關於迴圈變數n: 因為演算法中要求的是重排後數字的最大值與最小值之差。所以n是迴圈變數。
執行結果:
錯誤程式:
錯誤或可優化部分分析:
1. (錯誤)變數名混用導致棋藝:c和C混用了,難以分清c 和C的具體含義。根據程式理解可能是:(1)個位十位百位三個數字中的一個。(好像小寫c是這個意思);(2)重排後的差。(好像大寫C是這個意思)。但在while迴圈判斷的時候用錯了。
2. (可能是錯誤)個位十位百位計算過程應該向上移動若干行:這裡是否是個錯誤,主要看你對演算法實現的過程,還有就是演算法中的迴圈變數使用的是哪個。
3. (可優化)定義的變數最好不要用double:因為這裡要求的數字範圍總是整數,並且不超過3位數,所以用 int 型別最方便。用double雖然不算錯誤,但會在計算過程中轉化為int型別,所以用double沒必要。在具體程式中根據具體型別選擇適當的資料型別即可,不必使用更寬範圍的型別。
4. (可優化)求個位、十位、百位數字計算的優化:(假設表示式中用的是重排後的差,下面說明中我改成了大寫C)
a = ((int)C/100)%10; (int)C/100 結果是百位數之前的部分,因為C是三位數,所以(int)C/100結果是百位數。因為C是三位數,雖然這裡沒錯但沒必要再進行 %10 求餘。
另外就是因為定義C是double型別,實際計算是用int型別,所以這裡使用了強制型別轉換,反而更麻煩。