Tìm lỗi chương trình tính tổng 2 phân số trong c++

Ai tìm giúp mình lỗi ở đâu với ạ

#include <iostream>
using namespace std;

struct PhanSo
{
	int tuSo;
	int mauSo;
};

void nhap(PhanSo phanSo)
{
	cin >> phanSo.tuSo;
	cin >> phanSo.mauSo;
}

int timMauChung(PhanSo phanSo1, PhanSo phanSo2)
{
	int tich2Mau = phanSo1.mauSo * phanSo1.mauSo;
	int mauChung;
	if (phanSo1.mauSo >= phanSo2.mauSo)
	{
		for(int i = phanSo1.mauSo; i <= tich2Mau; i++)
			if (i % phanSo1.mauSo == 0 && i % phanSo2.mauSo == 0)
			{
				mauChung = i;
				break;
			}
	}
	else
	{
		for (int i = phanSo2.mauSo; i <= tich2Mau; i++)
			if (i % phanSo1.mauSo == 0 && i % phanSo2.mauSo == 0)
			{
				mauChung = i;
				break;
			}
	}
	return mauChung;
}

PhanSo cong2PhanSo(PhanSo phanSo1, PhanSo phanSo2)
{
	int mauChung = timMauChung(phanSo1, phanSo2);
	PhanSo phanSo3;
	phanSo3.tuSo = phanSo1.tuSo * (mauChung / phanSo1.mauSo) + phanSo2.tuSo * (mauChung / phanSo2.mauSo);
	phanSo3.mauSo = mauChung;
	return phanSo3;
}

int main()
{
	cout << "nhap phan so 1: ";
	PhanSo phanSo1;
	nhap(phanSo1);
	cout << "nhap phan so 2: ";
	PhanSo phanSo2;
	nhap(phanSo2);
	cout << "tong cua 2 phan so la: ";
	PhanSo phanSo3 = cong2PhanSo(phanSo1, phanSo2);
	cout << phanSo3.tuSo << "/" << phanSo3.mauSo;
	return 0;
}

merged to the #1 post by noname00

1 Like

Khá ổn rồi. Có điều trong hàm nhap() của bạn. Là bạn nhập cho bản sao của phanSo1phanSo2.

Đơn giản sửa thành void nhap(PhanSo &phanSo) là song. :slight_smile:

Bạn cũng nên kiểm tra điều kiện nhập mẫu bằng 0 để tránh rủi ro về sau. :slight_smile:

1 Like

À, cảm ơn bác, nhưng bác xem giúp e thuật toán với, chạy thì chỉ cộng đc 2 phân số cùng mẫu, khác mẫu là lại lỗi

À, nó bắt phải khai báo và khởi tạo ngay giá trị cho biến mauChung, nhưng chạy đc thì lại có phân số cộng đúng, có cái lại ra 0/0 :thinking:

Chà:

4/5*100
(4*100)/5

Bạn nghĩ 2 kết quả bằng nhau không?
KQ:

4/5*100 = 0
(4*100)/5 = 80

Đó là kết quả phép chia của số nguyên đấy. Nên ép về số thực (float, double) trước khi chia.

3 Likes

Nhưng cái mauChung là bội của 2 cái mauSo mà bác, làm sao chia ra số lẻ đc

1 Like

Do chỗ này nè. :smile:

Phải là int tich2Mau = phanSo1.mauSo * phanSo2.mauSo; chớ. :laughing:


Góp ý cho bạn hàm cộng phân số của mình nè. :slight_smile:

PhanSo add(PhanSo ps1, PhanSo ps2) {
    PhanSo ps3;
    ps3.mauSo = ps1.mauSo * ps2.mauSo;
    ps3.tuSo = ps1.tuSo * ps2.mauSo + ps2.tuSo * ps1.mauSo;
    int t = ps3.mauSo > ps3.tuSo ? ps3.tuSo : ps3.mauSo;
    for (int i = 2; i * i <= t; i++) {
        while (!(ps3.tuSo % i) && !(ps3.mauSo % i)) {
            ps3.tuSo /= i;
            ps3.mauSo /= i;
        }
    }
    return ps3;
}
4 Likes

Oh, cám ơn bạn, mình ẩu quá, với lại code của bạn code bằng ngôn ngữ j đó, mình mới học c vs c++ cơ bản nên ko bít

1 Like

Vẫn là C++ thôi :smiley:

Mẫu mực thì nó ntn cơ :smiley:

int gcd(int a, int b) {
  // a, b >= 0
  return b == 0 ? b : gcd(a, a % b);
  // return a == 0 || b == 0 ? a + b : gcd(b, a%b); // dễ hiểu hơn
}

// static function
int Fraction::Dem(const Fraction &f1, const Fraction &f2) {
  return f1.dem == f2.dem ? f1.dem : f1.dem / gcd(f2.dem, f1.dem) * f2.dem;
}
3 Likes

Em cũng định dùng LCM rồi nhưng mà lời viết (phải viết cả GCD trc :smile:).

Cơ mà thấy GCD của anh hơi có vấn đề thì phải. Sao lại là a + b nhỉ. :thinking:


// a, b > 0

int gcd(int a, int b) {
	if (!a && !b) return -1;
	if (a < b) return gcd(b, a);
	if (!b) return a;
	else return gcd(b, a % b);
}

int lcm(int a, int b) {
	return a * b / gcd(a, b);
}
1 Like

Vì gcd(0, 0) = 0 là đúng.

Để ý là cuối cùng ta cũng phải trả lời gcd(0, n) bằng bao nhiêu (và nó bằng n).

1 Like

Sao lại bằng 0 nhỉ. 0 làm gì có ước nhỉ. Nếu có ước là 0 thì phải chia được cho 0. :thinking:

1 Like

Nếu số này chia hết cho số kia thì số kia có thể xem là <= số này (hay quan hệ chia hết là quan hệ thứ tự)

hide cho đỡ shock

0 chia hết cho mọi số tự nhiên vậy 0 là to nhất :smiley: nên gcd(0, n) = n.

0 chia hết cho 0 vì 0 * n = 0 (định nghĩa).

Vậy “b | a <=> a / b là số nguyên” là SAI vì 0 | 0 nên phải thêm điều kiện.

4 Likes

Thấy trc khi hide òy. :slight_smile:

Giờ em ms bít, thêm kt ms. Thanks đại ca.

1 Like

viết vậy cho ngắn hơn :V

return b ? gcd(b, a % b) : a;

check remainder (ở đây là b) khác 0 là được rồi check a khác 0 chi nữa :V

ko đệ quy:

while (b)
{
    a %= b;
    std::swap(a, b);
}
return a;

chôm từ Boost :kissing_closed_eyes:

6 Likes

Với đầu vào a > b nữa a. :slight_smile:

1 Like

Không, do số bị chia trở thành số chia sau mỗi lần lặp :smiley:

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?