Bài tập pascal về Phân số

Mình có các bài tập cô giáo giao bài tập về nhà mà không pít sao cả các bạn giúp đỡ
viết chương trình thực hiện các công việc sau
- nhập vào 2 phân số ( từ tệp)
- trả các kết quả của hai phân số trên ( + , - ,* /, so sánh, tối giản)
- yêu cầu : sử dụng mảng 1 chiều để xử lí các phân số
 

tengiday

Happy life
Reply: bài tập pascal

Mình chỉ nói về lưu 2 phân số thôi nhé, còn việc đọc mình assume rằng bạn làm đc. Giả sử như dữ liệu vào đúng đắn (mẫu số <> 0), theo như đề bài, mình sẽ dùng 1 mảng gồm 2 phần tử với phần tử đầu là tử số và phần tử thứ 2 là mẫu số. Vì đề ko nói rõ nên mình cho rằng tử và mẫu số đều là số nguyên. Mình cũng giả sử luôn là giới hạn của tử và mẫu số hợp lý để khi nhân lại ko bị tràn biến.
Mã:
type fraction = array[1..2] of integer;
var a, b, c : fraction;
- Trước tiên, bạn cần 1 hàm tìm UCLN dùng để đơn giản phân số.
- Sau đó thì đơn giản phân số.
- Tiếp theo là các hàm +, -, *, /, và so sánh. Ví dụ đơn giản:
Hàm cộng:
Mã:
function add(a, b : fraction) : fraction;
var c : fraction;
begin
    simplify(a); simplify(b);
    if (b[1] = 0) then exit(a);
    if (a[1] = 0) then exit(b);
    c[1] := a[1] * b[2] + a[2] * b[1];
    c[2] := a[2] * b[2];
    simplify(c);
    exit(c);
end;
Hàm nhân:
Mã:
function mult(a, b : fraction) : fraction;
var c : fraction;
begin
    simplify(a); simplify(b);
    c[1] := 0; c[2] := 1;
    if (a[1] = 0) or (b[1] = 0) then exit(c);
    c[1] := a[1] * b[1];
    c[2] := a[2] * b[2];
    simplify(c);
    exit(c);
end;
Những hàm còn lại bạn nên tự viết; nếu ko đc thì post code lên để mọi ng` xem giúp cho nhé. Nhìn chung, bạn làm tay như thế nào thì viết cho máy chạy như thế.
 
Reply: bài tập pascal

cảm ơn bạn đã giúp đỡ, có chỗ này mình chưa rõ
mình nhin vao mã của bạn. mình cũng hình dung được như thế này
có phải là ban dùng mảng a lưu tử, b lưu mẫu,c la kết quả phải không ak
nhứng chỗ này mình ko rõ
- mình chỉ mới thường làm là lưu các số nguyên vào mảng thì được đằng này là phân số
nên mình chưa biết đằng lưu, nhờ bạn chỉ dùm

mình hỏi thêm chỗ này
nếu đề cho như thế này thì mình làm cách nào để lưu hả bạn
VD cho n = 5
1/5 2/9 7/15 4/9 12/15
rồi mình cũng thực hiện các công việc trên cho dạng này thì làm sao hả bạn
 

tengiday

Happy life
Reply: bài tập pascal

- Bạn xem kĩ lại post #2 của mình: a, b, và c đều là mảng cả. Mảng này chỉ gồm 2 phần tử để lưu tử số và mẫu số.
Ví dụ: phân số 1/4 đc lưu ở 'a' sẽ là a[1] := 1, a[2] := 4.
- Nếu như input file theo như bạn ghi thì có 2 cách đọc những phân số này: đọc từng character một xử lý, hoặc là đọc nguyên 1 dòng thật dài vào (lưu ý cần dùng AnsiString).
 
Sửa lần cuối:
Reply: bài tập pascal

vậy là mình nhầm rồi mảng a lưu phân số 1, b lưu phân số 2
c lưu phân số kết quả
ý bạn đọc từng chacrer một xử lý có phải là như thế này ko ak
bạn xem sửa cho mình với
readln(f,n)
for i:= 1 to n do
read(f,..)mình chưa biết cách lưu chỗ này vì vd 1/4 cho dấu gạch ngang mình không biết xử lý sao
chưa biết làm thế nào để đưa 1 vào a[1] 4 vào a[2]
nhờ bạn code mẫu một chương trình tính tổng phân số cho mình hiểu dược ko ak
 

tengiday

Happy life
Reply: bài tập pascal

Nói thật, mình đã hơn 10 năm chưa code nhập xuất dữ liệu bằng Pascal rồi. Mình chỉ viết sơ sơ pseudo-code nó thôi nhé, chưa test và mình ko chạy Pascal trên máy.
Mình giả sử như dữ liệu đúng đắn. Đoạn code sau để đọc nguyên dãy phân số vào.
Mã:
readln(f, n);
k := 0;
s := chuỗi rỗng
while (not eof(f)) do
    begin
        read(f, ch);
        if (ch là chữ số từ '0' tới '9' hoặc ch là dấu '-') then
            s := s + ch
        else if (ch = '/' and s <> chuỗi rỗng) then   // đây là tử số
            begin
                inc(k);
                val(s, a[k, 1], code);
                Gán s là chuỗi rỗng.
            end
        else if (ch = ' ' and s <> chuỗi rỗng) then   // đây là mẫu số
            begin
                val(s, a[k, 2], code);   // chỗ này cũng có thể kiểm tra phân số có valid hay không nữa.
                simplify(a[k]);
                Gán s là chuỗi rỗng.
             end;
    end;
val(s, a[k, 2], code);
simplify(a[k]);
Đoạn code này là để đơn giản phân số. Mình viết như vầy vì mình muốn phân số nhìn "đẹp" mắt.
Mã:
procedure simplify(var a : fraction);
var t : integer;
     sign : shortint;
begin
    if (a[1] = 0) then
        begin
            a[2] := 1;
            exit;
        end;
    if ((a[1] < 0) and (a[2] < 0)) or ((a[1] > 0) and (a[2] > 0)) then
        sign := 1
    else
        sign := -1;
    t := gcd(abs(a[1]), abs(a[2]));   // UCLN của tử số và mẫu số
    a[1] := sign * abs(a[1]) div t;
    a[2] := abs(a[2]) div t;
end;
 
Sửa lần cuối:
Reply: bài tập pascal

chỗ này mình không rõ lắm val(s, a[k, 1], code) đổi s ra số lưu vào mảng a tại vị trí k+ 1 hả bạn
- vậy khí gồm n phân số như trên có phải mảng a sẽ lưu ntn này phải ko bạn
mình đang hinh dung mang a cái đã rồi mới dám nghĩ đên vấn đề khac

vd n 4
1/5 1/9 23/24 45/50 sẽ được lưu như sau

151923244550


- vấn đề tiếp theo như bạn làm ở trên thì trươc khi thực hiện các phép + - * / so sanh các phân số mình cần tối giản đi hả bạn
 

tengiday

Happy life
Reply: bài tập pascal

Sau khi đọc 4 số đó thì mảng a nó như thế này. Đây là mảng 2 chiều bạn nhé. 'a[k, 1]' là phần tử nằm ở dòng k, cột 1 của mảng 'a'.
15
19
2324
910

Nếu phân số trong mảng 'a' đã tối giản rồi thì ko cần tối giản một lần nữa lúc đầu chương trình +, -, *, /, và so sánh.
 
Reply: bài tập pascal

thật sự mà nói với dạng bài toán về phân số thế này mình khó hình dung quá
nếu bạn giúp được có thê trình bày một chương tinh tông
n sphân ố như trên ,minh mới có thể hiểu và áp dụng cho các bài khác được
nếu được vậy thank bạn nhiều vì mới hoc mà áp dụng thế này.hai nưa kiến thức của mình hạn chế quá
 

tengiday

Happy life
Reply: bài tập pascal

Bởi vì ban đầu bạn ghi chỉ có 2 phân số nên mình mới ghi thế. Bạn học mảng tới đâu rồi? Phân số có nhiều cách biểu diễn, nhưng chỉ tóm gọn lại thành 2 dạng: tử số 1 biến, mẫu số 1 biến; hoặc dùng record lưu 2 biến thành 1. Nếu chọn cách đầu thì để lưu đc nhiều phân số, bạn cũng có nhiều cách: dễ nhất thì dùng array 2 chiều, hoặc dùng 2 mảng 1 chiều lưu tử và mẫu số riêng.
Bạn nên bắt đầu thế này. Bây giờ mở file, đọc phân số vào, rồi in nó ra để bạn có thể hình dung đc phân số nó lưu như thế nào trong mảng. Mình có 1 bảng, hay là array 2 chiều gồm n dòng và 2 cột. Mỗi dòng lưu 1 phân số, cột 1 lưu tử số, và cột 2 lưu mẫu số,
a = phân số thứ i, nằm ở dòng thứ i của mảng 'a'.
a[i, 1] = tử số của phân số thứ i, nằm ở dòng thứ i và cột 1 của mảng 'a'.
a[i, 2] = mẫu số của phân số thứ i, nằm ở dòng thứ i và cột 2 của mảng 'a'.
Mã:
type fraction = array[1..2] of integer;
var a : array[1..1000] of fraction;
      n : integer;
      result : fraction;

procedure read_file();
begin
..................................
..................................
end;

begin
    read_file();   // đoạn code ở trên của mình, bạn thêm assign, reset, close này nọ vào. Bỏ luôn dòng simplify ra cho dễ.
    writeln(a[1, 1], '/', a[1, 2]);   // phân số thứ 1
    writeln(a[2, 1], '/', a[2, 2]);   // phân số thứ 2

    result := sum(a[1], a[2]);   // khi bạn đã hiểu đoạn trên thì tính tổng 2 phân số xem thử.
    writeln(result[1], '/', result[2]);
end.
Nếu bạn dùng mảng 1 chiều hoàn toàn để lưu n phân số như post #7 của bạn thì phân số thứ i nó sẽ là:
Mã:
a[2 * i - 1]: tử số phân số thứ i
a[2 * i] : mẫu số phân số thứ i
 
Sửa lần cuối:
Reply: bài tập pascal

mình mới học mảng của mảng 1 chiều thôi ak
mình muốn xử lý bài này bằng mảng 1 chiều bạn đưa ra cho mình nhiều cách giải quá nên mình cũng hơi lúng túng trong việc tiếp cận bài toán.bạn chi tiết hơn cho mình bằng 1 chiều với ak (lưu n phân số vào mảng 1 chiều sau đó tính tổng phân số có trong mảng)
VÌ hiện tại mới tiếp cận nên mình cần 1 bài mẫu từ đó mình mới triển khai được
 

tengiday

Happy life
Bạn nghĩ phân số đơn giản một chút. Phân số chỉ là 1 cặp số mà thôi (cũng giống như sau này bạn lưu tọa độ vậy), tức là cần 2 biến để lưu nó. Cho đơn giản, với bài này, bạn dùng 2 mảng 1 chiều để lưu: mảng 'a' để lưu tử số, và 'b' để lưu mẫu số. Ví dụ:
Mã:
i    1      2       3        4       5
    1/4    3/5    -2/7      9/2     0/1
a    1      3      -2        9       0
b    4      5       7        2       1

var a, b : array[1..1000] of integer;
Như vậy khi bạn đọc file vào, số nào đứng trước dấu '/' thì là tử số, phải lưu vào mảng 'a'. Số nào đứng sau thì là mẫu số, phải lưu vào mảng 'b'. Đọc file vào y chang lúc trước, chỉ đổi chỗ lưu biến mà thôi. Bạn lưu phân số vào trước, in nó ra cho hiểu rõ nhé.
Mã:
readln(f, n);
k := 0;
s := chuỗi rỗng
while (not eof(f)) do
    begin
        read(f, ch);
        if (ch là chữ số từ '0' tới '9' hoặc ch là dấu '-') then
            s := s + ch
        else if (ch = '/' and s <> chuỗi rỗng) then   // đây là tử số
            begin
                inc(k);
                val(s, a[k], code);
                Gán s là chuỗi rỗng.
            end
        else if (ch = ' ' and s <> chuỗi rỗng) then   // đây là mẫu số
            begin
                val(s, b[k], code);   // chỗ này cũng có thể kiểm tra phân số có valid hay không nữa.
                Gán s là chuỗi rỗng.
             end;
    end;
val(s, b[k], code);
Phần đơn giản phân số phải thay đổi lại:
Mã:
// Đơn giản phân số   'numerator' = tử số  và   'denominator' = mẫu số
procedure simplify(var numerator, denominator : integer);
var sign, t : integer;
begin
    if (numerator = 0) then
        begin
            denominator := 1;
            exit;
        end;
    if ((numerator < 0) and (denominator < 0)) or ((numerator > 0) and (denominator > 0)) then
        sign := 1
    else
        sign := -1;
    t := gcd(abs(numerator), abs(denominator));   // UCLN của tử số và mẫu số
    numerator := sign * abs(numerator) div t;
    denominator := abs(denominator) div t;
end;
Phép cộng 2 số thì như thế này.
Mã:
procedure sum(c, d, e, f : integer; var x, y : integer);   // c/d + e/f = x/y
begin
    x := c * f + e * d;
    y := d * f;
    simplify(x, y);
end;
Bạn cần hiểu cộng 2 số trc rồi mới làm đc cộng n số nhé.
 
Sửa lần cuối:
readln(f, n);
k := 0;
s := chuỗi rỗng
while (not eof(f)) do
begin
read(f, ch);
if (ch là chữ số từ '0' tới '9' hoặc ch là dấu '-') then
s := s + ch
else if (ch = '/' and s <> chuỗi rỗng) then // đây là tử số
begin
inc(k);
val(s, a[k], code);
Gán s là chuỗi rỗng.
end
else if (ch = ' ' and s <> chuỗi rỗng) then // đây là mẫu số
begin
val(s, b[k], code); // chỗ này cũng có thể kiểm tra phân số có valid hay không nữa.
Gán s là chuỗi rỗng.
end;
end;
val(s, b[k], code);//mình chưa rõ chỗ này vì ở trên đã lưu mẫu số vào mảng b rồi mà bạn,làm việc này có tác dụng j nữa bạn
 
sau khi bạn xây dựng các thủ tục trên mình chỉ cần gọi lại để tính tổng 2 phân số thôi phải không bạn
thủ tục ghi
procedure ghidl;
var f: text ;
begin
assign(f,fo);
rewrite(f);
write(f, x,'/', y);
close(f);
end;

begin
docdl;
sum(a[1], a[2],b[1], b[2]);
ghi;
end.
vậy có đúng không bạn
- nhờ bạn chỉ dẫn cách tính tổng n phân số cho mình luôn với ak
 

tengiday

Happy life
readln(f, n);
k := 0;
s := chuỗi rỗng
while (not eof(f)) do
begin
read(f, ch);
if (ch là chữ số từ '0' tới '9' hoặc ch là dấu '-') then
s := s + ch
else if (ch = '/' and s <> chuỗi rỗng) then // đây là tử số
begin
inc(k);
val(s, a[k], code);
Gán s là chuỗi rỗng.
end
else if (ch = ' ' and s <> chuỗi rỗng) then // đây là mẫu số
begin
val(s, b[k], code); // chỗ này cũng có thể kiểm tra phân số có valid hay không nữa.
Gán s là chuỗi rỗng.
end;
end;
val(s, b[k], code);//mình chưa rõ chỗ này vì ở trên đã lưu mẫu số vào mảng b rồi mà bạn,làm việc này có tác dụng j nữa bạn
Cần phải có dòng đó vì con số cuối cùng chưa đc lưu vào mảng. Thật ra, bạn có thể bỏ dòng đó ra rồi chạy thử xem thế nào mà.
sau khi bạn xây dựng các thủ tục trên mình chỉ cần gọi lại để tính tổng 2 phân số thôi phải không bạn
thủ tục ghi
procedure ghidl;
var f: text ;
begin
assign(f,fo);
rewrite(f);
write(f, x,'/', y);
close(f);
end;

begin
docdl;
sum(a[1], a[2],b[1], b[2]);
ghi;
end.
vậy có đúng không bạn
- nhờ bạn chỉ dẫn cách tính tổng n phân số cho mình luôn với ak
Bạn phải dùng 'sum' mình ghi ở post #12 mới đc. Để tính tổng n phân số thì làm thế này:
Mã:
procedure addF();
var i : integer;
begin
    x := 0; y := 1;
    for i := 1 to n do sum(x, y, a[i], b[i], x, y);   // chỗ này tương tự như s := s + a[i].
end;
Như thế là 99.9% chương trình rồi đó nhé. Kết quả lưu ở 'x' và 'y'. Bạn cần thêm simplify vào nữa là đẹp rồi.
 
tong hai phân sô mình hiểu rồi mình nhờ bạn nói lại chỗ này
sum(x, y, a, b, x, y)
 

tengiday

Happy life
có nghĩa bạn gán phân số đầu tiên
VD : 0/1+ 1/5 phai ko bạn
Đúng rồi đấy. Khi i = 1,
0/1 + 1/5 = 1/5

Khi đó x = 1 và y = 5. Rồi sau đó i = 2 tương tự.
1/5 + ... = ??/??

Bởi vậy, mình có dòng comment là s = s + a đấy.
 
mình hỏi bạn phần này nữa là dk rồi
- trong thủ thục simplify có biến sign trả về hai kết quả 1 -1 mục đich của cái này làm gì hở bạn
- với lại khi đơn giản phân số ta cần một hàm ucln nữa là dk bạn hi
 

Thống kê

Chủ đề
100,657
Bài viết
467,424
Thành viên
339,832
Thành viên mới nhất
tiendungmobi
Top