CÁC MỞ RỘNG CỦA C++

Bài tập có hướng dẫn

Viết hàm GiaiPTBậc2() sau, hàm này trả về số nghiệm n và giá trị các nghiệm x1, x2 (nếu có) của một phương trình bậc 2 với các hệ số a, b, c:

void GiaiPTBậc2 (float a, float b, float c, int &n, float &x1, float &x2);

Hướng dẫn:
void GiaiPTBậc2 (float a, float b, float c, int &sn, float &x1, float &x2) {
	float delta = b*b – 4*a*c ;
	if(delta < 0)
		sn = 0;
	else if(delta == 0) {
		sn = 1;
		x1 = x2 = -b / (2*a);
	}
	else {
		sn = 2;
		x1 = (-b + sqrt(delta)) / (2*a);
		x2 = (-b - sqrt(delta)) / (2*a);
	}
}
		
Viết hàm SapXep() sau, hàm thực hiện sắp xếp một mảng số nguyên theo chiều tăng dần hoặc giảm dần, mặc định kiểu sắp xếp là tăng dần.

void SapXep(int a[], int n, int flag = 0);

Khi tham số hình thức thứ ba nhận giá trị mặc định bằng 0 hàm sắp xếp tăng dần, ngược lại hàm sắp xếp giảm dần.

Hướng dẫn:
void Nhap(int a[], int n) {
	do {
		<Nhap n>
	} while(n < 1 || n > SIZE);
	for(int i = 0; i < n; i++) {
		cout << "Phan tu thu " << i <<":";
		cin >> a[i];
	}
}
void Xuat(int a[], int n) {
	for(int i = 0; i < n; i++)
		cout << a[i] <<"\t";
	cout <<"\n";
}
void SapXep(int a[], int n, int flag) {
	int i, j;
	for(i = 0; i < n-1; i++)
		for(j = i + 1; j < n; j++)
			if(flag == 0 ? a[i] > a[j] : a[i] < a[j]) {
				int tam = a[i];
				a[i] = a[j];
				a[j] = tam;
			}
}
void main() {
	int a[SIZE];
	int n;
	Nhap(a, n);
	Xuat(a, n);
	SapXep(a, n); //Sắp tăng dần
	Xuat(a, n);
	SapXep(a, n, 1); //Sắp giảm dần
	Xuat(a, n);
}
		
Sử dụng toán tử new để cấp phát vùng nhớ cho mảng động một chiều nguyên, sau đó thực hiện các thao tác sau:
  1. Nhập mảng.
  2. Xuất mảng.
  3. Tính tổng các phần tử là số nguyên tố.
  4. Sắp xếp các phần tử là số nguyên tố tăng dần.
  5. Tìm vị trí phần tử nguyên tố đầu tiên.
  6. Xóa phần tử nguyên tố đầu tiên.
  7. Sau khi thực hiện xong các thao tác thì sử dụng toán tử delete để giải phóng vùng nhớ đã được cấp phát trước đó.
Hướng dẫn:
//Hàm kiểm tra nguyên tố
int NguyenTo(int x) {
	int nt;
	if(x < 2)
		nt = 0; //Không là nguyên tố
	else {
		nt = 1; //Là nguyên tố
		for(int i = 2; i < x; i++)
			if(x % i == 0) {
				nt = 0;
				break;
			}
	}
	return nt;
}
//Câu 2a
void Nhap(int *p, int n) {
	do {
		printf("Nhap so phan tu:");
		scanf("%d", &n);
	} while(n < 1 || n > SIZE);
	for(int i = 0; i < n; i++) {
		printf("pt thu %d:", i);
		scanf("%d", &p[i]);
	}
}
//Câu 2b
void Xuat(int *p, int n) {
	for(int i = 0; i < n; i++)
		printf("%d\t", p[i]);
	printf("\n");
}
//Câu 2c
int TôngNT(int p[], int n) {
	int ret = 0;
	int i;
	for(i = 0; i < n; i++)
		if(NguyenTo(p[i]))
			ret += p[i];
	return ret;
}
//Câu 2d
void SapXepNTTang(int p[], int n) {
	int i, j;
	for(i = 0; i < n - 1; i++)
		for(j = i + 1; j < n; j++) {
			if(NguyenTo(p[i]) && NguyenTo(p[j]) && p[i] > p[j]) { /*so sánh p[i] và p[j]*/
				//Hoán vị p[i] và p[j]
				int tam = p[i];
				p[i] = p[j];
				p[j] = tam;
			}
}
//Câu 2e
int TimNTDauTien(int *p, int n) {
	int i, j;
	int ret = -1; //Không tìm thấy
	for(i = 0; i < n; i++)
		if(NguyenTo(p[i])) {
			ret = i;
			break;
		}
	return ret;
}
//Câu 2f
void xoa(int *p, int &n, int vt) {
	int i;
	if(vt < 0 || vt >= n)
		printf("Vi tri %d khong hơp le\n", vt);
	else {
		if(n == 0)
			printf("Mang rong\n")
		else {
			// Dời các phần tử từ vị trí vt + 1 đến n - 1 lên một vị trí
			for(i = vt; i <= n - 1; i++)
				p[i] = p[i + 1];
			//Giảm số phần tử xuống 1
			n--;
		}
	}
}
void XoaNTDauTien(int *p, int &n) {
	int vt = TimNTDauTien(p, n);
	if(vt != -1)
		Xoa(a, &n, vt);
	else
		cout << "Khong tim thay so NT\n";
}
//Hàm chính
void main() {
	int *p;
	int n;
	<Nhap n>
	p = new int[n];
	//Cấp phát vùng nhớ động
	Nhap(p, n);
	Xuat(p, n);
	cout << "Tong chinh phuong: " << TongCP(p, n) <<"\n";
	int vitri = TimNTDauTien(p, n);
	if(vitri != -1) {
		cout << " vi tri nguyen to dau tien: " << vitri <<"\n";
		Xoa(p, n, vitri);
		Xuat(p, n);
	}
	else {
		cout << "Khong tim thay nguyen to\n");
	}
	delete[]p;
	//Giải phóng vùng nhớ động
}
		
Khai báo kiểu dữ liệu DT để biểu diễn thông tin của một đa thức, sau đó định nghĩa các hàm sau:

void Nhap(DT &u);

//Nhập đa thức theo bậc tăng dần

void Xuat(const DT &u);

DT operator+(const DT &u, const DT &v); //Toán tử cộng hai đa thức

DT operator-(const DT &u, const DT &v); // Toán tử trừ hai đa thức

DT operator*(const DT &u, const DT &v); // Toán tử nhân hai đa thức

void operator-(DT &u);

// Toán tử đảo dấu đa thức

float operator^( const DT &u, float x); /*Toán tử tính giá trị đa thức tại x*/

Hướng dẫn:
#define SIZE 10
struct DT {
int n;
	//Bậc đa thức
	float arr[SIZE]; //Mảng chứa các hệ số của đa thức
};
void Nhap(DT &u) {
do {
	cout << "Nhap bac da thuc:";
		cin >> u.n;
	}while(u.n < 1 || u.n > SIZE);
	for(int i = 0; i < u.n + 1; i++) {
		cout << "Nhập hệ số thứ " << i <<":\n";
		cin >> u.arr[i];
	}
}
void Xuat(const DT &u) {
	for(int i = 0; i < u.n + 1; i++)
		cout << u.arr[i] <<"\t";
	cout << "\n";
}
DT operator+(const DT &u, const DT &v) {
	int k = (u.n > v.n ? u.n : v.n);
	DT ret;
	ret.n = k;
	for(int i = 0; i < ret.n + 1; i++) {
		if(i <= u.n && i <= v.n)
			ret.arr[i] = u.arr[i] + v.arr[i];
		else if(i <= u.n)
			ret.arr[i] = u.arr[i];
		else ret.arr[i] = v.arr[i];
	}
	return ret;
}
DT operator*(const DT &u, const DT &v) {
	int i, j;
	int k = u.n + v.n;
	DT ret;
	ret.n = k;
	//Khởi tạo các hệ số của đa thức ret bằng 0
	for(i = 0; i < ret.n + 1; i++)
		ret.arr[i] = 0;
	//Nhân hai đa thức
	for(i = 0; i < u.n + 1; i++)
		for(j = 0; j < v.n + 1; j++)
			ret.arr[i+j] += u.arr[i] * v.arr[j];
	retunr ret;
}
float operator^ (DT u, float x) {
	float ret = 0;
	float t = 1;
	for(int i = 0; i < u.n + 1; i++) {
		ret += u.arr[i] * t;
		t *= x;
	}
	return ret;
}
void operator-(DT &u) {
	for(int i = 0; i < u.n + 1; i++)
		u.arr[i] = -u.arr[i];
}
		

Bài tập luyện tập

Viết hàm GiaiPTTrungPhuong() sau, hàm này trả về số nghiệm sn và các nghiệm x1, x2 , x3, x4 (nếu có) của một phương trình trùng phương với các hệ số a, b và c:

void GiaiPTTrungPhuong (float a, float b, float c, int &sn, float &x1, float &x2, float &x3, float &x4);

Sử dụng toán tử new để cấp phát vùng nhớ động cho mảng hai chiều nguyên, sau đó thực hiện các thao tác sau:
Khai báo kiểu dữ liệu PS để biểu diễn thông tin của một phân số, sau đó định nghĩa các hàm sau:

void Nhap(PS &u);

void Xuat(const PS &u);

int USCLN(int x, int y);

void RutGon(PS &u) ;

//Toán tử số học

PS operator+(const PS &u, const PS &v);

PS operator-(const PS &u, const PS &v);

PS operator*(const PS &u, const PS &v);

PS operator/(const PS &u, const PS &v);

//Toán tử quan hệ

int operator>(const PS &u, const PS &v);

int operator>=(const PS &u, const PS &v);

int operator<(const PS &u, const PS &v);

int operator<=(const PS &u, const PS &v);

int operator==(const PS &u, const PS &v);

int operator!=(const PS &u, const PS &v);

//Toán tử số học mở rộng

void operator+=(PS &u, const PS &v);

void operator-=(PS &u, const PS &v);

void operator*=(PS &u, const PS &v);

void operator/=(PS &u, const PS &v);