Writing code exam questions
☺寫程式碼考題
簡單
影像的旋轉
假設有一灰階影像 img1,其類別為 Image 如下:
class Image {
private:
int width; // 寬
int height; // 高
unsigned char **pixel; // 像素
public:
Image(int w, int h); // 建構子
unsigned char getpixel(int r, int c); // 取出 pixel[r][c]值
void setpixel(int r, int c, unsigned char g);// 設定 pixel[r][c]值為 g
int getwidth(); // 取出影像的寬度
int getheight(); // 取出影像的高度
}
其寬為 width,高為 height,其像素值存在一個二維陣列 pixel 中,資料型態為 unsigned
char。今欲將此灰階影像 img1 順時針旋轉 90 度,並儲存在另一新的灰階影像 img2。
試寫出 Image 類別的建構子,依據參數 w(代表寬度)與 h(代表高度),可以動
態配置二維陣列 pixel。(10 分)
試完成 Image 類別的其他成員函式:getpixel( ),setpixel( ),getwidth( ),和
getheight( ),並寫出一個 PrtImg( )函式如下,列印影像 img 參數中 pixel 的值,其
中每一列(row)印完需跳行,像素值以空白隔開。(10 分)
void PrtImg(Image & img)
{
......
}
試寫出一個 Rotate( )函式如下,將參數 img1 順時針旋轉 90 度後,存成新的影像
img2,並回傳。(10 分)
Image Rotate(Image & img1)
{
......
}
以下是 Image 類別的完整定義:
#include <iostream>
class Image {
private:
int width; // 寬
int height; // 高
unsigned char **pixel; // 像素
public:
Image(int w, int h) : width(w), height(h) {
pixel = new unsigned char*[height];
for (int i = 0; i < height; i++) {
pixel[i] = new unsigned char[width];
}
}
~Image() {
for (int i = 0; i < height; i++) {
delete[] pixel[i];
}
delete[] pixel;
}
unsigned char getpixel(int r, int c) {
return pixel[r][c];
}
void setpixel(int r, int c, unsigned char g) {
pixel[r][c] = g;
}
int getwidth() {
return width;
}
int getheight() {
return height;
}
};
void PrtImg(Image & img) {
for (int i = 0; i < img.getheight(); i++) {
for (int j = 0; j < img.getwidth(); j++) {
std::cout << static_cast<int>(img.getpixel(i, j)) << " ";
}
std::cout << std::endl;
}
}
Image Rotate(Image & img1) {
Image img2(img1.getheight(), img1.getwidth());
for (int i = 0; i < img1.getheight(); i++) {
for (int j = 0; j < img1.getwidth(); j++) {
img2.setpixel(j, img1.getheight() - 1 - i, img1.getpixel(i, j));
}
}
return img2;
}
在上述程式碼中,我們定義了一個 Image 類別,其包含有寬度 width、高度 height 和像素值 pixel。在建構子中,我們使用 new 運算子動態配置二維陣列 pixel。在解構子中,我們使用 delete 運算子釋放動態配置的記憶體。
我們使用了成員函式 getpixel() 和 setpixel() 分別取出和設定像素值。在成員函式 getwidth() 和 getheight() 中,我們分別取出影像的寬度和高度。
在函式 PrtImg() 中,我們使用兩層迴圈來列印影像中的像素值。在函式 Rotate() 中,我們建立了一個新的影像物件 img2,並將參數影像 img1 順時針旋轉 90 度後存入其中。
最大公因數及最小公倍數
試以 C++來定義有理數(意即分數)類別 Rational 如下,其包含有分子 a 和分母 b,其
中分母 b 不能為 0。
class Rational {
private:
int a; // 分子
int b; // 分母
......
public:
......
};
假設 main( )的主程式,和其所執行輸出的結果如下:
Rational r0;
cout << "r0 = "; r0.prt( );
Rational r1(2, 4);
Rational r2(3, 6);
cout << "r1 = "; r1.prt( );
cout << "r2 = "; r2.prt( );
Rational r3 = r1+r2;
Rational r4 = r1-r2;
Rational r5 = r1*r2;
Rational r6 = r1/r2;
cout << "r1 + r2 = "; r3.prt( );
cout << "r1 - r2 = "; r4.prt( );
cout << "r1 * r2 = "; r5.prt( );
cout << "r1 / r2 = "; r6.prt( );
輸出結果:
r0 = 0/1
r1 = 1/2
r2 = 1/2
r1 + r2 = 1/1
r1 - r2 = 0/1
r1 * r2 = 1/4
r1 / r2 = 1/1
試列出完整的 Rational 類別定義。(10 分)
試完成所需的建構子(包含預設建構子),多載運算子(overloaded operators):加、
減、乘、除等,以及成員函式 prt( ),和相關的程式碼。注意:有理數輸出必須為
最簡分數,並藉機將有理數化簡成最簡分數。(20 分)
以下是 Rational 類別的完整定義:
#include <iostream>
#include <numeric>
class Rational {
private:
int a; // 分子
int b; // 分母
public:
Rational() : a(0), b(1) {}
Rational(int a, int b) : a(a), b(b) {}
void prt() const {
std::cout << a << "/" << b << std::endl;
}
friend Rational operator+(const Rational& r1, const Rational& r2) {
int lcm = std::lcm(r1.b, r2.b);
int numerator = r1.a * (lcm / r1.b) + r2.a * (lcm / r2.b);
return Rational(numerator / std::gcd(numerator, lcm), lcm / std::gcd(numerator, lcm));
}
friend Rational operator-(const Rational& r1, const Rational& r2) {
int lcm = std::lcm(r1.b, r2.b);
int numerator = r1.a * (lcm / r1.b) - r2.a * (lcm / r2.b);
return Rational(numerator / std::gcd(numerator, lcm), lcm / std::gcd(numerator, lcm));
}
friend Rational operator*(const Rational& r1, const Rational& r2) {
return Rational(r1.a * r2.a / std::gcd(r1.a * r2.a, r1.b * r2.b), r1.b * r2.b / std::gcd(r1.a * r2.a, r1.b * r2.b));
}
friend Rational operator/(const Rational& r1, const Rational& r2) {
return Rational(r1.a * r2.b / std::gcd(r1.a * r2.b, r1.b * r2.a), r1.b * r2.a / std::gcd(r1.a * r2.b, r1.b * r2.a));
}
};
在上述程式碼中,我們定義了一個 Rational 類別,其包含有分子 a 和分母 b。我們使用了 C++11 的 std::lcm 和 std::gcd 函式來求最小公倍數和最大公因數。在 prt() 函式中,我們將有理數以最簡分數的形式輸出。
我們使用了運算子重載來實現加、減、乘、除等運算。在運算時,我們先求出兩個有理數的最小公倍數,然後將分子相加、相減、相乘、相除,再將結果化簡成最簡分數。
以下是 main() 函式的程式碼:
int main() {
Rational r0;
std::cout << "r0 = ";
r0.prt();
Rational r1(2, 4);
Rational r2(3, 6);
std::cout << "r1 = ";
r1.prt();
std::cout << "r2 = ";
r2.prt();
Rational r3 = r1 + r2;
Rational r4 = r1 - r2;
Rational r5 = r1 * r2;
Rational r6 = r1 / r2;
std::cout << "r1 + r2 = ";
r3.prt();
std::cout << "r1 - r2 = ";
r4.prt();
std::cout << "r1 * r2 = ";
r5.prt();
std::cout << "r1 / r2 = ";
r6.prt();
return 0;
}
在 main() 函式中,我們建立了四個有理數物件 r0、r1、r2、r3、r4、r5 和 r6。然後我們使用運算子重載來實現加、減、乘、除等運算,並將結果輸出為最簡分數
照類別圖設計程式
要點
- 如何用java enum
- 如何取得java現在時間
- 如何用list資料結構新增資料,與iterate
- 重寫override
請使用物件導向程式語言(C#或 Java),設計一具門禁功能的智慧卡管理資訊系統。
系統應依如下的 class diagram 建立相關的類別資訊。(35 分
所有的類別變數皆為 private,SMsecurity 類別繼承自抽象類別 SmartCard
z 發卡單位 Organization、進出入狀況 EnterExit,請分別使用 enum 的格式來表示
z 記錄進出入狀況,日期資料若未提供,則填入目前系統的日期時間
z 一張智慧卡,會有多次的進出入記錄,資料值應存放於 List 線性資料結構中
z 改寫系統的 toString()方法後,執行如下的測試動作
SMsecurity sms = new SMsecurity("SM001", Organization.NewTaipeiMRT);
sms.addInfo("2015/06/15 18:36:01", EnterExit.Enter);
sms.addInfo("2015/06/15 20:16:01", EnterExit.Exit);
sms.addInfo("2015/06/20 18:20:01", EnterExit.Enter);
sms.addInfo(EnterExit.Exit);
/* for Java */ System.out.println(sms.toString());
/* for C# */ Console.WriteLine(sms.ToString());
應能產生類似如下的結果
*****Smart card SM001 (6/21/2015 10:38:38 PM, NewTaipeiMRT)
-----Enter and Exit information:
(2015/06/15 18:36:01, Enter)
(2015/06/15 20:16:01, Exit)
(2015/06/20 18:20:01, Enter)
(6/21/2015 10:38:38 PM, Exit)
Comments
Post a Comment