c语言int输入1输出60000,数字的秘密问题分析(C语言)
數字的秘密問題分析(C語言)
原創---子衿兄
1
【問題】
在數字王國中,人人都有一個號碼,人人想個號碼對自己意味著什么。國一他不是你做了很多個盒子,每個盒子擁有一個號碼。人們需要通過一定的方法才能確定哪個例子有自己的秘密。這個辦法就是把自己的數字N的全部因子相加求和。例如12,他因子之和就是1+2+3+4+6=16。現在他們邀請你幫助編寫一個函數 ,尋找他們的密碼盒子。
**輸入:**輸入數據的第一行是一個數字
T(1<=T<=50000),它表明有1個需要進行測試的數字,然后1個測試數據,每個測試數據為一個數字N(1<=N<=50000).
**輸出 :**對于每個測試數據,請輸出一個代表輸入數據的密碼編號 。
例:
輸入:
3
2
10
20
輸出:
1
8
22
注:由于測試數據關系,如果N==0的話,請輸出1
【分析需求】
分析下題目,會發現,題目中有很多包裝或場景性術語,歸根到底,它的要求就是求一組的數因子之和,是數據問題。具體細化它的要求:
1) 要計算因子和的數有T個,這個數目不固定,動態輸入,有一個范圍是[1,50000]
2) 求它的全部因子,注意因子包括1,,但不包括它本身。
3) 每個數值也是有范圍[1,50000], 0也可以,但輸出 因子固定為1
4) 輸入輸出是每行顯示一個數。
【設計】
經過上面的需求分析,那我們就要進行概要設計
1、 分配存放測試數據的空間
2、 輸入需要測試多少個數,T ,由于<50000,用int就可以
3、 輸入所有測試數據
4、 求每一個測試數據所有因子,并計算其和
5、 打印所有結果
【編碼】
圖片發自簡書App
源代碼就如此,你會發現這個代碼很簡單就實現了我們的功能,輸入輸出是否和要求一致,到這里貌似我們已經完成了任務,是否結束了?那么我肯定的告訴你,這個代碼是幼兒小班同學寫的,別不信,我們從以下幾個維度來分析此代碼。
1、 從功能完整性
前面的分析里提到,我們輸入的數據是可以為0,只不過固定為1,那么我們運行上面的代碼,會發現輸出為0
圖片發自簡書App
那這肯定說明我們代碼有考慮不到的地方。
原因就在于30行,我們是從1開始除的,默認這里的數是大于等于1,所以我們要關注為0的時候故需要修改代碼
圖片發自簡書App
2、從數據安全
題目中有要求僌的數據個數范圍為[1,50000],也就是說最多不能超過50000,我們的代碼用于存儲數據大小是50001,其實也是有風險的,假如我輸入了60000個數據,那么這個數組在使用的時候就會越界,可能會使用到其他空間,嚴重引起系統異常。由于數據量太大,我3個數為例作演示。
圖片發自簡書App
那么我們就需要對輸入數據進行有效判斷 ,確認是在這個范圍,修改代碼
圖片發自簡書App
同樣,我們也要對測試數據進行類似的判斷,因為題目中有要求
圖片發自簡書App
大伙再看看,數據都覆蓋完了嗎?
很遺憾,依然沒有,如果輸入一個負數呢?
圖片發自簡書App
可以修改為:
圖片發自簡書App
那么大家再想想,是否有其他辦法,比如將數據類型修改無符號是否可行?
3、從存儲空間利用率
題目中有要求輸入的數據個數最大為50000,所以我們之前申請的數組大小就為50001*sizeof(int),但實際上我們開始驗證的時候只輸了幾個數,你們可以想想,我們提著大尼龍口袋去銀行只取了100塊錢放在里面,是不是感覺大材小用了。這種在資源比較緊張的嵌入式設備里絕對絕對不允許這么 做的。又要按照題目要求動態輸入個數,那么只好使用動態申請空間嘍
圖片發自簡書App
別忘了用完了得釋放
圖片發自簡書App
4、 從執行效率
當數據 特別大的時候,我們可以看到在求所有因子時是從1遍歷到N-1,但事實上是完全不用的,最基礎,最簡單的提升效率就是只算[1,N/2],想想為什么?
圖片發自簡書App
還有更多更好的優化,就不詳述了,大伙自行去想想!
4、 從代碼規范
看起來這代碼挺規范的,沒有什么可以改善的了,其實不然
1) 所有的參數要初始化喲,包括前面的數組,指針,變量等。
圖片發自簡書App
注意這里是指第一次使用前初始化。
2) 編寫的函數要做到功能單一,所以一般來說要將求因子之和放到一個單獨的函數中去,main調用
圖片發自簡書App
3)注意編碼安全規范,像scanf這些屬于非安全函數,要修改成安全函數
如scanf_s
4)其他如命名,返回值定義,異常處理,入參判斷等
經過上面五個方面的改進,基本上可以用了,是不是覺得寫個代碼不容易!哈哈!我這里只是拋磚引玉,可能各位還會發現有需要優化的哈,僅作參考。
1
注:本文屬原創,若轉載請注明出處!
附代碼
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
//求輸入n的所有因子之和
int factor(int n) {
int j;
int sum = 0;
if (n == 0)
return 1;
for (j = 1; j <= n / 2; j++) {
if (n % j == 0)
sum += j;
}
return sum;
}
int main() {
int T = 0;? //需要測試數據的個數
int *N_p = NULL;? //N[50001]; //可能測試的數據會有50000個
int i,j,temp; //臨時變量
int sum; //因子之和
//獲取測試數據
scanf("%d", &T);
if ((T < 0 ) || (T > 50000)) {
printf("輸入數據個數超過要求\n");
return -1;? ? //這里是要退出呢,還是再重輸,各位看著辦
}
N_p = (int*)malloc(T * sizeof(int));
if (N_p == NULL) {
printf("malloc fail\n");
return -2;
}
//獲取T個測試數據
for (i = 0; i < T; i++) {
scanf("%d", N_p+i);
if ((T < 0) || (T > 50000)) {
printf("輸入測試數據超過[1,5000],退出\n");
return -1;? ? //這里是要退出呢,還是再重輸,各位看著辦
}
}
//求每個數據的全部因子,計算其和,并打印
for (i = 0; i < T; i++) {
sum = factor(*(N_p + i));
printf("%d\n", sum);
}
if (N_p) {
free(N_p);
N_p = NULL;
}
return 0;
}
文章最后發布于: 2019-11-10
總結
以上是生活随笔為你收集整理的c语言int输入1输出60000,数字的秘密问题分析(C语言)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云计算机的价值,云计算现在的价值都有哪些
- 下一篇: 织梦php数据库修改密码,如何使用php