深セン大学コンピュータソフトウェア「オブジェクト指向プログラミング」実験10 単一継承

A. 3D 空間内の点 (継承)

トピックの説明

点から原点までの距離を計算する getDistance() メンバー関数を含む平面上の点 C2D クラスを定義します。C2D クラスから 3 次元空間点 C3D クラスを派生し、その getDistance() メンバー関数を次のようにします。点から原点までの距離を計算します。 原点からの距離。C2D オブジェクトと C3D オブジェクトをそれぞれ生成して、原点までの距離を計算してみます。

3 次元空間内の 2 点( x 、 y 、 z ) (x、y、z)× z ( x 1 , y 1 , z 1 ) (x_1, y_1, z_1)×1y1z1)距離の式は次のとおりです。

d = ( ( x − x 1 ) 2 + ( y − y 1 ) 2 + ( z − z 1 ) 2 ) 1 2 d = ((x-x_1)^2+(y-y_1)^2+(z -z_1)^2)^{\frac{1} {2}}d=(( xバツ1)2+( yy1)2+( zz1)2 )21

入力

1行目の2次元座標点の位置

2行目1の3D座標点の位置

3次元座標点位置2の3行目

出力

1行目の2次元座標点の位置から原点までの距離

位置 1 から 2 行目の 3D 座標点の原点までの距離

3次元座標点位置2の3行目から原点までの距離

4行目の2次元座標点変数に3次元座標点位置2を代入した後、2次元座標点から原点までの距離

入力サンプル1

3 4
3 4 5
6 8 8

出力サンプル1

5
7.07107
12.8062
10

ACコード

#include<iostream>
#include<cmath>
using namespace std;

class C2D {
    
    
	double x, y;
public:
	C2D(double x = 0, double y = 0) :x(x), y(y) {
    
    }
	double getX() {
    
     return x; }
	double getY() {
    
     return y; }
	double get_distance() {
    
    
		return sqrt(x * x + y * y);
	}
};


class C3D :public C2D {
    
    
	double z;
public:
	C3D(double x = 0, double y = 0, double z = 0) :C2D(x, y), z(z) {
    
    }
	double get_distance() {
    
    
		return sqrt(getX() * getX() + getY() * getY() + z * z);
	}
};

int main() {
    
    
	double x, y, x1, y1, z1, x2, y2, z2;
	cin >> x >> y >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;

	C2D p(x, y);
	C3D p1(x1, y1, z1), p2(x2, y2, z2);
	C2D p4 = p2;

	cout << p.get_distance() << endl;
	cout << p1.get_distance() << endl;
	cout << p2.get_distance() << endl;
	cout << p4.get_distance() << endl;

}

B. 生徒の成績計算 (継承と多態性)

トピックの説明

名前や年齢などの属性と、基本情報を出力する表示関数を持たせるためのPersonクラスを定義します。

「オブジェクト指向プログラミング」コースを受講する学生は、パーソン クラスに基づいて、リスニングフリーの学生とリスニングフリーの学生というサブクラスを派生します。サブクラスは親クラスのメンバーを継承し、他のメンバーを追加し、表示関数を書き換えます。

非オーディション学生は、平常点、テスト得点、総合評価点の3つの属性があり、総合評価点は(平常点40%+テスト得点60%)で計算され、85点以上がA、 75点(含む)~85点(含まない)はB、65点(含む)~75点(含まない)はC、60点(含む)~65点(含まない)はD、60点(含まない)含む)以下はFとなります。

リスニングフリーの生徒の属性はテスト得点と総合評価得点の 2 つだけであり、総合評価得点は上記の成績体系に対応するテスト得点に 100% 基づきます。

上記のクラスを定義して main 関数を記述し、型記号を入力します。 R を入力した場合は、生徒の基本情報、通常の成績とテストのスコアに基づいて非リスニングの生徒オブジェクトを作成します。 S を入力した場合は、非リスニングの生徒オブジェクトを作成します学生の基本情報とテストスコアオブジェクトに基づく学生オブジェクト。生徒の総合成績を計算して出力します。

入力

テスト数 t

後続の各行には、学生のタイプに関する情報が入力されます。

出力

各生徒の基本情報と総合成績

入力サンプル1

2
R シンディ 18 100 100
S サンディ 28 59

出力サンプル1

シンディ 18 A
サンディ 28 F

ACコード

#include<iostream>
#include<cmath>
using namespace std;

class Person {
    
    
	string name;
	int age;

public:
	Person(string name, int age) :name(name), age(age) {
    
    }
	void display() {
    
     cout << name << " " << age << " "; }
};


class Student1 :public Person {
    
    
	int score1, score2;
	int score;
public:
	Student1(string name, int age, int s1, int s2) :Person(name, age), score1(s1), score2(s2) {
    
    
		score = 0.4 * score1 + 0.6 * score2;
	}

	char getGrade() {
    
    
		if (score >= 85)
			return 'A';
		if (score >= 75)
			return 'B';
		if (score >= 65)
			return 'C';
		if (score >= 60)
			return 'D';
		return 'F';
	}


	void display() {
    
    
		Person::display();
		cout << getGrade() << endl;
	}

};

class Student2 :public Person {
    
    
	int score2;
	int score;
public:
	Student2(string name, int age, int s) :Person(name, age), score(s), score2(s) {
    
    }
	char getGrade() {
    
    
		if (score >= 85)
			return 'A';
		if (score >= 75)
			return 'B';
		if (score >= 65)
			return 'C';
		if (score >= 60)
			return 'D';
		return 'F';
	}


	void display() {
    
    
		Person::display();
		cout << getGrade() << endl;
	}

};


int main() {
    
    
	int t;
	cin >> t;
	while (t--) {
    
    
		char c;
		string name;
		int age;
		cin >> c >> name >> age;
		if (c == 'R') {
    
    
			int s1, s2;
			cin >> s1 >> s2;
			Student1(name, age, s1, s2).display();
		}
		else{
    
    
			int s;
			cin >> s;
			Student2(name, age, s).display();
		}
	}

	return 0;
}

C. 通帳とクレジットカード(相続)

制限時間
1秒
メモリ制限
128MB

トピックの説明

通帳クラス CAccount を定義します。通帳クラスには、口座番号 (account、long)、名前 (name、char[10])、残高 (balance、float) などのデータ メンバーと、入金を実現できるその他のデータ メンバーが含まれます (deposit、操作が成功した場合は「保存 OK!」と表示されます))、出金 (出金、操作が成功した場合は「出金 OK!」)、残高確認 (チェック)、出金額は残高の範囲内である必要があります。それ以外の場合は、"ごめんなさい!バランスオーバー!」と表示されます。

クレジット カード クラス CCreditcard は、通帳クラスから派生しています。クレジット カード クラスは、当座貸越限度額 (リミット、フロート) をデータ メンバーとして追加し、限度額の範囲内で当座貸越額を許可するように出金操作が変更されます。制限を超えると、「申し訳ありません! 制限を超えています!」というプロンプトが表示されます。この質問では、残高がマイナスになる場合があることに注意してください。たとえば、残高が 500、当座貸越額が 500、出金額が 800 の場合、残高は -300 になります。

main 関数を作成し、これら 2 つのクラスのオブジェクトを作成してテストします。

1. 通帳クラスの場合、口座番号、名称、残高を入力後、残高照会、入金、残高照会、出金、残高照会の順にクラスメソッドを呼び出して出力します。

2. クレジットカードクラスの場合、口座番号、名前、残高、当座貸越限度額を入力後、残高照会、入金、残高照会、出金、残高照会の順にクラスメソッドを呼び出して出力します。

入力

口座名義残高

入金額

出金額

口座名 残高 当座貸越限度額

入金額

出金額

出力

勘定残高

入金操作結果

勘定残高

出金操作結果

勘定残高

勘定残高

入金操作結果

勘定残高

出金操作結果

勘定残高

入力サンプル1

1000 トム 1000
500
1000
2000 ジョン 500 500
500
1501

出力サンプル1

残高は1000
貯金OK!
残高は1500
出金ok!
残高は500
残高は500
貯金OK!
残高は1000です
ごめんなさい!限度を超えて!
残高は1000です

ACコード

#include<iostream>
#include<cmath>
using namespace std;

class CAccount {
    
    
	long account;
	string name;
	double balance;
public:
	CAccount(long account, string name, double balance) :account(account), name(name), balance(balance) {
    
    }
	void withdraw(double v) {
    
    
		if (v > balance) {
    
    
			cout << "sorry! over balance!" << endl;
			return;
		}
		balance -= v;
		cout << "withdraw ok!" << endl;
	}
	void deposit(double v) {
    
    
		balance += v;
		cout << "saving ok!" << endl;
	}
	void printBalance() {
    
    
		cout << "balance is " << balance << endl;
	}

	double getBalance() {
    
     return balance; }
	void setBalance(double v) {
    
     balance = v; }

};

class CCreditcard :public CAccount {
    
    
	double limit;
public:
	CCreditcard(long account, string name, double balance, double limit) :CAccount(account, name, balance), limit(limit) {
    
    }
	void withdraw(double v) {
    
    
		if (getBalance() + limit < v) {
    
    
			cout << "sorry! over limit!" << endl;
			return;
		}
		setBalance(getBalance() - v);
		cout << "withdraw ok!" << endl;
	}
};


int main() {
    
    
	long id, id1;
	string name, name1;
	double v, v1, v2, t;
	cin >> id >> name >> v;
	CAccount c1(id, name, v);
	c1.printBalance();
	cin >> t;
	c1.deposit(t);
	c1.printBalance();
	cin >> t;
	c1.withdraw(t);
	c1.printBalance();

	cin >> id1 >> name1 >> v1 >> v2;
	CCreditcard c2(id1, name1, v1, v2);
	c2.printBalance();
	cin >> t;
	c2.deposit(t);
	c2.printBalance();
	cin >> t;
	c2.withdraw(t);
	c2.printBalance();
	return 0;
}

D. 円と円柱の計算 (継承)

トピックの説明

データ メンバー x、y (座標点) を含む CPoint 点クラスを定義します。

CPointを基底クラスとして円クラスCCircleを導出し、データメンバr(半径)と円の面積を計算するメンバ関数を追加します。

次に、CCircle を直接の基本クラスとして取得し、円柱クラス CCylinder を派生し、データ メンバー h (高さ) とメンバー関数を追加して体積を計算します。

円および円柱オブジェクトを生成し、メンバー関数を呼び出して面積または体積を計算し、結果を出力します。

入力

円の中心位置と半径を入力します

円柱の中心位置、半径、高さを入力してください

出力

出力円の中心位置の半径

出力円領域

出力シリンダー中心位置の半径高さ

シリンダー出力容積

入力サンプル1

0 0 1
1 1 2 3

出力サンプル1

円:(0,0),1
面積:3.14
円柱:(1,1),2,3
体積:37.68

ACコード

#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;

class CPoint {
    
    
	double x, y;
public:
	CPoint(double x, double y) :x(x), y(y) {
    
    }
	double getX() {
    
     return x; }
	double getY() {
    
     return y; }
	void print() {
    
     cout << "(" << getX() << "," << getY() << ")"; }
};

class CCircle :public CPoint {
    
    
	double r;
public:
	CCircle(double x, double y, double r) :CPoint(x, y), r(r) {
    
    }
	void print() {
    
    
		cout << "Circle:";
		CPoint::print();
		cout << ",";
		cout << r << endl;
		cout << "Area:" << getArea() << endl;
	}

	double getArea() {
    
    
		return 3.14 * r * r;
	}

	double getR() {
    
     return r; }

};

class CCylinder :public CCircle {
    
    
	double h;
public:
	CCylinder(double x, double y, double r, double h) :CCircle(x, y, r), h(h) {
    
    }

	double getVolume() {
    
    
		return h * getArea();
	}

	void print() {
    
    
		cout << "Cylinder:";
		CPoint::print();
		cout << "," << getR() << "," << h << endl;
		cout << "Volume:" << getVolume() << endl;
	}
};


int main() {
    
    
	double x, y, z, x1, y1, z1, h;
	cin >> x >> y >> z >> x1 >> y1 >> z1 >> h;
	CCircle(x, y, z).print();
	CCylinder(x1, y1, z1, h).print();
	return 0;
}

E. クロックシミュレーション(継承)

トピックの説明

保護されたデータ メンバーの値とパブリック関数の増分カウントに 1 を加えた値を含むカウンター クラスを定義します。

カウンタ クラスを継承する循環計算器を定義し、プライベート データ メンバーを増やします: 最小値 min_value、max_value、

パブリック関数のincrementを書き換えて、値がmin_value~max_valueの範囲内でcycle+1するようにします。

クロック クラスを定義します。データ メンバーは、プライベート ループ カウンター オブジェクト、時、分、秒です。パブリック関数 time(int s) は、現在時刻が s 秒経過した後の時刻、つまり新しい値を計算します。時、分、秒。

クロック クラス オブジェクトを定義し、現在時刻と経過秒数を入力し、time 関数を呼び出して新しい時刻を計算します。

トピックの要件に従って、必要なコンストラクター、デストラクター、およびその他の必要な関数を追加します。

Clock はシステムの組み込み関数であるため、名前の重複を避けるために、Clock をクラス名または関数名として使用しないでください。

入力

最初の行のテストの数 n

2 行のグループ。最初の行は現在の時刻 (時、分、秒)、2 行目は経過秒です。

出力

n 行出力します

各行は、現在時刻と、秒数が経過した後に計算される新しい時刻 (時:分:秒) の各セットに対応します。

入力サンプル1

2
8 19 20
20
23 30 0
1801

出力サンプル1

8:19:40
0:0:1

ACコード

#include<iostream>
#include<iomanip>
using namespace std;

class Counter {
    
    
protected:
	int value;
public:
	Counter(int value = 0) :value(value) {
    
    }
	void increment() {
    
     value++; }
	void changeValue(int v) {
    
     value = v; }
	int getValue() {
    
     return value; }
};

class Computer :public Counter {
    
    
	int min_value, max_value;
public:
	Computer(int min_value, int max_value, int v = 0) :Counter(v), min_value(min_value), max_value(max_value) {
    
    }
	bool increment() {
    
     value++; if (value > max_value) {
    
     value = min_value; return true; }return false; }
};

class Clock {
    
    
	Computer hour, minute, second;
public:
	Clock() :hour(0, 23), minute(0, 59), second(0, 59) {
    
    
		int h, m, s;
		cin >> h >> m >> s;
		hour.changeValue(h);
		minute.changeValue(m);
		second.changeValue(s);
	}

	void time(int s = 1) {
    
    
		if (s == 0)
			return;
		if (second.increment())
			if (minute.increment())
				hour.increment();
		time(s - 1);
	}
	void print() {
    
     cout << hour.getValue() << ":" << minute.getValue() << ":" << second.getValue() << endl; }

};


int main() {
    
    
	int n;
	cin >> n;
	while (n--) {
    
    
		int hour, minute, second;
		Clock c;
		int t;
		cin >> t;
		c.time(t);
		c.print();
	}
	return 0;
}

F.新旧IDカード(継承)

トピックの説明

次のように、15 桁の ID 番号を記述する日付クラス CDate と古い ID カード クラス COldID を定義します。

クラスCDate

{

プライベート:

int 年、月、日;

公共:

CDate(int,int,int);

bool check(); // 日付が有効かどうかをチェックします

bool isLeap();

void print();

};

クラスCOldID

{

プライベート:

char *p_id15, *p_name; //15桁のID番号、名前

CDate 誕生日; // 生年月日

公共:

COldID(char *p_idval, char *p_nameval, CDate &day);

bool check(); //15桁のIDカードが合法かどうかを検証する

void print();

~COldID();

};

次に、COldID を基本クラスとして使用して、18 桁の ID 番号を持つ新しい ID カード クラス CNewID を派生し、p_id18 (18 桁の数値)、issueday (発行日)​​、および validyear (有効期間、年数) の 3 つのデータ メンバーを追加します。 )、check()とprint()を再定義します。

IDカードの18桁の認証コードの生成方法:

1. ID カード番号の最初の 17 桁に、7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2 を掛けます。それからそれを加算します。

2. 17 桁の数値と係数の乗算と加算の和を 11 で割って余りを求めます。

3. 剰余とチェックコードの対応は、1,0,X,9,8,7,6,5,4,3,2となります。つまり、余りが 3 の場合、ID カードの 18 桁目は 9 になります。余りが2の場合、IDカードの下一桁はXになります。

main関数は派生クラスオブジェクトを定義し、その派生クラスオブジェクトでcheck()を呼び出し、falseを返した場合は「illegal id」を出力し、それ以外の場合はprint()を呼び出してIDカード情報を出力します。ID カードの有効性を検証するための check() ルール:

  1. 15桁のIDカードが正しいことを確認してください。

  2. 15桁の数字を拡張した18桁の数字と、18桁目のチェックコードが正しいことを確認してください。

  3. ID カードの生年月日は法的に有効です。

  4. ID 番号に不正な文字は含まれていません。

  5. ID 番号の長さは正しいです。

  6. IDカードは有効期限内です(2017年5月10日)

入力

テストデータのグループ数 t

一人目の氏名、生年月日、15桁のID番号、18桁のID番号、発行年月日、有効期限(長期処理として100年)

2人目の氏名、生年月日、15桁のID番号、18桁のID番号、発行年月日、有効期限(長期処理として100年)

出力

一人称の名前

本人の18桁のID番号情報(番号、発行日、有効期限)または「不正ID」

二人称の名前

2人目の18桁のID番号情報(番号、発行日、有効期限)または「不正なID」

入力サンプル1

10
AAAA 1988 2 28 440301880228113 440301198802281133 2006 1 20 20
BBBB 1997 4 30 440301980808554 440301199808085541 2015 2 2 10
CCCC 1920 5 8 530102200508011 53010219200508011X 1980 3 4 30
DDDD 1980 1 1 340524800101001 340524198001010012 1998 12 11 20
EEEE 1988 11 12 110203881112034 110203198811120340 2007 2 29 20
FFFF 1964 11 15 432831641115081 432831196411150810 2015 8 7 100
GGGG 1996 12 10 44030196121010 44030119961210109 2014 6 7 20
HHHH 1988 7 21 440301880721X12 44030119880721X122 2006 5 11 20
IIII 1976 3 30 440301760330098 440301197603300983 2003 4 15 20
JJJJ 1955 9 5 440301550905205 440301195509051052 2004 6 4 100

出力サンプル1

AAAA
440301198802281133 2006年1月20日 20年
BBBB
不正ID
CCCC
不正ID
DDDD
不正ID
EEEE
不正ID
FFFF
432831196411150810 2015年8月7日 長期GGGG 不正
ID
HHHH
不正
ID
IIII
不正ID
JJJJ
不正ID

ACコード

#include<iostream>
#include<string>
using namespace std;

class CDate
{
    
    
private:
	int year, month, day;
public:
	CDate(int y, int m, int d) :year(y), month(m), day(d) {
    
    }
	bool check() {
    
    
		int days[] = {
    
     0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (isLeap())
			days[2] += 1;
		return month >= 1 && month <= 12 && day >= 1 && day <= days[month];
	}

	bool isLeap() {
    
    
		if (year % 4 == 0 && year % 100 != 0)
			return true;
		if (year % 400 == 0)
			return true;
		return false;
	}

	void print() {
    
    
		cout << year << "年" << month << "月" << day << "日" << " ";
	}


	int getYear() {
    
    
		return year;
	}

	int getMonth() {
    
    
		return month;
	}

	int getDay() {
    
    
		return day;
	}

	string get_8_char() {
    
    
		string s1 = to_string(year);
		//s1.erase(0, 2);
		string s2 = to_string(month);
		if (s2.length() == 1)
			s2 = "0" + s2;
		string s3 = to_string(day);
		if (s3.length() == 1)
			s3 = "0" + s2;
		return s1 + s2 + s3;
	}


	string get_6_char() {
    
    
		string s = get_8_char();
		return s.substr(2);
	}
};

class COldID
{
    
    
private:
	string p_id15, p_name; //15位身份证号码,姓名
	CDate birthday; //出生日期
public:
	COldID(string p_idval, string p_nameval, CDate day) :p_id15(p_idval), p_name(p_nameval), birthday(day) {
    
    }
	bool check() {
    
    
		return p_id15.find(birthday.get_6_char()) != string::npos;
	}
	void print() {
    
     cout << p_id15 << " "; }
	CDate getBirthday() {
    
     return birthday; }

	string get18id() {
    
    
		string id = p_id15.substr(0, 6) + "19" + p_id15.substr(6);
		int a[] = {
    
     7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 };
		char b[] = {
    
     '1','0','X','9','8','7','6','5','4','3','2' };
		int sum = 0;
		for (int i = 0; i < 17; i++)
			sum += a[i] * (id[i] - '0');
		sum %= 11;
		id.push_back(b[sum]);
		return id;
	}

	string getName() {
    
     return p_name; }
};

class CNewID :public COldID {
    
    
	string p_id18;
	CDate issueday;
	int validyear;
public:
	CNewID(string name, int year, int month, int day, string id15, string id18, int y, int m, int d, int v)
		:COldID(id15, name, CDate(year, month, day)), p_id18(id18), issueday(y, m, d), validyear(v)
	{
    
    }

	bool check() {
    
    
		if (p_id18.length() != 18)
			return 0;
		if (!isdigit(p_id18[17]) && p_id18[17] != 'X')
			return 0;
		if (!COldID::check())
			return 0;
		if (get18id() != p_id18) {
    
    
			//cout << get18id() << endl;
			//cout << p_id18 << endl;
			return 0;
		}
		if (!getBirthday().check())
			return 0;
		if (!issueday.check())
			return 0;
		for (int i = 0; i < 17; i++)
			if (!isdigit(p_id18[i]))
				return 0;

		if (validyear == 100)
			return 1;

		if (issueday.getYear() + validyear > 2017)
			return 1;
		if (issueday.getYear() + validyear < 2017)
			return 0;

		if (issueday.getMonth() > 5)
			return 1;
		if (issueday.getMonth() < 5)
			return 0;
		if (issueday.getDay() > 10)
			return 1;
		return 0;

	}

	void print() {
    
    
		cout << getName() << endl;
		if (!check()) {
    
    
			cout << "illegal id" << endl;
			return;
		}
		cout << p_id18 << " ";
		issueday.print();
		if (validyear != 100)
			cout << validyear << "年" << endl;
		else
			cout << "长期\n";
	}

};

int main() {
    
    
	int t;
	cin >> t;
	while (t--) {
    
    
		string name;
		int y, m, d;
		string id1, id2;
		int y1, m1, d1;
		int valid;
		cin >> name >> y >> m >> d >> id1 >> id2 >> y1 >> m1 >> d1 >> valid;
		CNewID c(name, y, m, d, id1, id2, y1, m1, d1, valid);
		c.print();

	}
	return 0;
}

おすすめ

転載: blog.csdn.net/weixin_46655675/article/details/129325543