2014年4月10日 星期四

iStudy C Rivew參考解答

練習題
1.輸入月份,輸出該月天數
	int m;
	printf("請輸入月份", &m);
	scanf("%d", &m);
	if(m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m ==  12) {
		printf("%d月有31天", m);
	}
	if(m == 4 || m == 6 || m == 9 || m == 11) {
		printf("%d月有30天", m);
	}
	if(m == 2) {
		printf("%d月有28天", m);
	}
2.輸入一數字n,輸出1+2+....+n之答案,若n<0提示輸入錯誤
	int n, i, sum = 0;
	printf("請輸入n >");
	scanf("%d", &n);
	if(n > 0) {
		for(i = 1;i <= n;i++)
			sum +=i;
		printf("%d\n", sum);
	} else {
		printf("數字有誤\n");
	}
3.承2,若n<0,提示輸入錯誤,並重新輸入直到n>0為止(利用for)
	int n, i, sum = 0;
	for(;;)
	{
		printf("請輸入n >");
		scanf("%d", &n);
		if(n < 0) {
			printf("數字有誤\n");
		} else {
			break;
		}
	}

	for(i = 1;i <= n;i++) {
		sum +=i;
	}
	printf("%d\n", sum);
4.同3,利用while改寫
	int n, i, sum = 0;

	printf("請輸入n >");
	scanf("%d", &n);
	if(n < 0) {
		printf("數字有誤\n");
	}

	while(n < 0) {
		printf("請輸入n >");
		scanf("%d", &n);
		if(n < 0) {
			printf("數字有誤\n");
		}
	}
	for(i = 1;i <= n;i++) {
		sum = sum+i;
	}
	printf("%d\n", sum);
解題 1.輸入一個數,找最大質因數
  • 解法1
  • 	int n, max;
    	scanf("%d", &n);
    	int m;
    	for(m = 1;m <= n;m++) {
    		int i;
    		for(i = 2;m%i != 0 && i <= m/2;i++);
    		if(i <= m/2)
    			continue;
    	} 
    	if(n%m == 0) {
    		max = m;
    	}
    	printf("%d 的最大質因數為 %d", n, max);
    
  • 解法2
  • 	int n, max;
    	scanf("%d", &n);
    	int m;
    	for(m = 1;m <= n;m++) {
    		int i, flag = 0;
    		// 用flag去標記m是不是質數,如果被整除,他就不是質數,標記為0
    		for(i = 2;i <= m/2;i++) {
    			flag = 1;
    			if(m%i == 0) {
    				flag = 0;
    				break;
    			}
    		}
    
    		//若 flag被標記為1,表示m為質數,則驗證m是否為n的因數
    		if(flag == 1 && n%m == 0) {
    			max = m;
    		}
    	}
    	printf("%d 的最大質因數為 %d", n, max);
    
2.類題-質因數分解
	int n;
	scanf("%d", &n);
	int m = 2;
	while(n > 1) {
		if(n%m == 0) {
			n = n/m;
			printf("%d ", m);
		} else {
			m++;
		}
	}
3.利用輾轉相除法處理GCD(HCF)最大公因數問題
	int m, n, temporary;
	printf("請輸入第一個數字 >");
	scanf("%d", &m);
	printf("請輸入第二個數字 >");
	scanf("%d", &n);
	printf("GCD(%d, %d) = ", m, n);

	if(n > m) {
		temporary = m;
		m = n;
		n = temporary;
	}

	while(n > 0) {
		temporary = n;
		n = m%n;
		m = temporary;
	}
	printf("%d", m);
4.Bonus-輸入一個包含年月份的日期,計算他是該年的第幾天(考慮閏年)
	int year, month, day, totalDay = 0;
	printf("請輸入 西元年 月 日(以空白分隔) >");
	scanf("%d %d %d", &year, &month, &day);

	/* 
		先判斷閏年
		閏年定義:年份為4的倍數且不為100的倍數,或者為400的倍數。
	*/
	int flag = 0; //閏年標記 0=不閏年, 1=閏年
	if(year%4 == 0 && year%100 != 0) {
		flag = 1;
	}

	if(year%400 == 0) {
		flag = 1;
	}

	/*
		檢查日期有沒有問題,我們設定條件
		1.不考慮西元前
		2.月份介於1~12
		3.日期不能超該月天數
	*/

	int error = 0; //如果三個參數有錯error被設為1
	if(year < 0 || month > 12 || month < 1) {
		error = 1;
	} else {
		if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month ==  12) {
			if(day > 31)
				error = 1;
		}
		if(month == 4 || month == 6 || month == 9 || month == 11) {
			if(day > 30)
				error = 1;
		}
		if(month == 2 && flag == 0) {
			if(day > 28)
				error = 1;
		}

		if(month == 2 && flag == 1) {
			if(day > 29)
				error = 1;
		}
	}

	/*
		1.先把month-1之前的天數算完
		2.再把該月的日期加上
	*/
	if(error == 0) {
		int i;
		for(i = 1;i < month;i++) {
			if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i ==  12) {
				totalDay += 31;
			}
			if(i == 4 || i == 6 || i == 9 || i == 11) {
				totalDay += 30;
			}
			if(i == 2 && flag == 0) {
				totalDay += 28;
			}

			if(i == 2 && flag == 1) {
				totalDay += 29;
			}
		}

		totalDay += day;

		printf("%d年%d月%d日是這一年的第%d天\n", year, month, day, totalDay);
	} else {
		printf("輸入的日期不支援\n");
	}

2013年9月26日 星期四

模組化(Modular)

這學期開始的Data Structure課程所要寫的程式架構勢必比上學期的Program Language課程大上很多,為了使得龐大的程式能夠被切割、分組成容易維護的小單位,模組化的概念顯的重要許多。C語言中,模組化的時候我們通常搭配header file來實作,下面做簡單講解。

模組化(Modular)

模組化本身是一種把實體抽象化的過程,把原本實際存在的東西轉換成概念、定義、模型、範本、架構的過程。

打個比方好了,我們常常在寫報告的時候會參考一些範本,我們會在範本當中找到一些寫報告的格式、必備內容等等通則。

像是普物實驗報告基本具備格式:Topic、Abstract、Introduction、Experimental Design、Data Analysis & Discussion、Conclusion

每一份普物實驗報告基本上都脫離不了這種格式,他們之間的差異只在於內容

若我們從程式的structure概念來看,他們都擁有屬性(資料)種類都一樣,差異在於屬性(資料)被設定的值(value)

因此我們可以想成定義一個structure就好比先行建立好一個沒有內容的報告的格式。

我們可以把報告格式想成是一個模組,而定義structure就是在建立模組(Module)



報告格式本身是不具有任何意義的,我們最後所要交出去的是一份真正的報告,而不是報告的格式。

每當我們想要寫報告的時候,就依照格式把資訊填入,一份報告就完成了

同樣的,我們依照structure所規定的資料格式填入值,而產生一個實際真正儲存資料的結構變數,在程式的概念當中我們稱為實體(instance)。

程式語言課曾經提過,function是一種模組化的手段。不知道各位當時是否有完全體會到這句話的意思,這邊簡單說明一下:

試著回想一下,會被獨立成為function的程式碼,大部分都是具有一些固定且單一用途,例如資料排序、交換位置、計算平方、印出資料、搜尋重複等等。

獨立出來的function就點類似特定功能的SOP一般,呼叫function就會去執行特定的功能,而這樣建立function的行為也是一種模組化的表現。也因為是一種模組化表現,因此我們在建立function都會追求「功能單一化、簡單化」的目標,避免建立一個功能複雜的function。


模組化的實作

在C/C++當中,建立模組時通常都是 1個 header file(*.h) + 1個 Source file (*.cpp)。

一般狀況下這兩個檔案會取一樣的名稱,只有副檔名不同。而檔案名稱通常是模組的名字。

I.header file(*.h) 

通常在header file當中我們會寫下類似下列資訊:
  1. struct的定義
    ex.
    struct Demo {
     int demoInt;
    };
    
  2. 函式原型prototype
    ex.
    int add_function(int, int);
  3. 定義常數
    ex.
    #define NUMBER_OF_STUDENT 5
  4. library的載入
    ex.
    #include <stdio.h>

II.Source file (*.cpp)

在cpp的部分則是撰寫函式的定義(definition),在這邊我們只把管方法怎麼做,不管實際資料如何。
ex.
int add_function (int a, int b) {
 return a+b;
}

寫完了.h和.cpp,到這邊為止模組就算完成建立了。

III.模組的套用

在一個新開的專案當中,我們要使用已經建立的模組時,只要遵循兩個步驟:
  1. 將.h和.cpp加入到專案當中
  2. 在要使用模組的原始碼最開頭利用「#include "header file名稱.h"」將他載入
例如這次的作業

做完了上述兩個動作,你就可以如往常使用function和structure的方式去使用已經被模組化的function和structure。

2013年7月17日 星期三

[C]大數乘法 - N階乘

實作一個計算 N階乘(N ! = N×(N-1) ×…×2×1)的程式。
(1) 請先試著看看,使用一般的 int 整數,最多可以實做到幾階乘?
(2) 實作一個支援大數運算(設定為可印出最高 1000位)的階乘程式,輸出 N!的值(N為一
輸入值,1<N<=200)。

[C]Perfect Number

Perfect Number

定義「A positive integer is a perfect number if it is equal to the sum of all its factors except itself.」。

例如:6 = 1 + 2 + 3;28 = 1 + 2 + 4 + 7 +14。

請以「隨機」的方式將 10000以內的 Perfect Number 印出。