bàI TẬP XỬ LÝ SỐ NGUYÊN LỚN MỌI NGƯỜI GIÚP VỚI

Cho số X gồm N chữ số, Số Y gồm M chữ số (1<=M<=32000; 1<=N<=32000)).
Yêu cầu: Tính hiệu 2 số X và Y.
Dữ liệu vào: Cho trong file văn bản HIEU.INP có cấu trúc như sau:
Dòng 1: Ghi 2 số nguyên dương N M mỗi số cách nhau một dấu cách.
Dòng 2: Ghi số X
Dòng 3: Ghi số Y
Dữ liệu ra: Ghi ra file HIEU.OUT, theo cấu trúc như sau:
Dũng 1: Ghi giá trị hiệu.
Ví dụ:
HIEU.INPHIEU.OUT
3 4
333
5436
-5103

giúp mình làm bằng mảng 1 chiều với ak
 

tengiday

Happy life
Bạn có thể tham khảo post #29 trong bài viết này của mình:
Mã:
https://vfo.vn/t/showthread.php?93595-Giai-thich-giup-minh-thuat-toan-cua-bai-nay-cho-minh-voi-kho-qua-/page3
 
cho mình hỏi chút, khi mình viết được hàm so sánh hai mảng rồi mình sẽ gọi hàm này tại thủ tục trừ pải không bạn!
khi đó
trong procedure trừ
sẽ là
t := compare(a, na, b, nb);
if t =1 then
lấy a - b
else
if t=-1 then
lấy b - a phải thế khổng hả bạn
cho mình hỏi thêm với bài này thi hàm compare chỉ cầnn trả về hai kết quả thôi pai ko bạn

 

tengiday

Happy life
cho mình hỏi chút, khi mình viết được hàm so sánh hai mảng rồi mình sẽ gọi hàm này tại thủ tục trừ pải không bạn!
khi đó
trong procedure trừ
sẽ là
t := compare(a, na, b, nb);
if t =1 then
lấy a - b
else
if t=-1 then
lấy b - a phải thế khổng hả bạn
cho mình hỏi thêm với bài này thi hàm compare chỉ cầnn trả về hai kết quả thôi pai ko bạn

Bạn nên làm nó bên ngoài procedure differences nhé. Ví dụ như:
Mã:
t := compare(a, na, b, nb);
if (t > 0) then
   begin
      differences(a, na, b, nb);
      in ra kết quả chứa trong a.
   end
else if (t < 0) then
   begin
      differences(b, nb, a, na);
      in ra kết quả chứa trong b.
   end
else
   in ra số 0.
PS: Mình chưa xử lý số âm nhé.
 
Sửa lần cuối:
Bạn ơi bạn sosanh t>0 với t< 0 co nghĩa la hàm sosanh trả về hai kqua la 1 và -1 phải ko bạn
 

tengiday

Happy life
Bạn ơi bạn sosanh t>0 với t< 0 co nghĩa la hàm sosanh trả về hai kqua la 1 và -1 phải ko bạn
Đúng rồi đó bạn; mình ghi thế cho ngắn gọn. Tương tự như a - b > 0, a - b < 0, hay a - b = 0 vậy.

PS: Mình quên mất 1 vấn đề quan trọng, khi t < 0 (tức là a < b) thì kết quả phải là số âm. Khi đó bạn cần 1 dòng lệnh nữa nhé.
Mã:
b[nb] = -b[nb];
 
Mảng a la mang chứa kết quả của phép trừ a - b còn mảng b là phep trừ của b - a .còn khi phep sosanh= 0 ta ko can tính và in ra ngay la số 0 ý tương nôm na có pải vậy ko bạn
 
Nình mới đọc lai bài bạn viết.dong lệnh mà bạn nói se nằm khi minh in mảng b ra hả bạn
 

tengiday

Happy life
Mảng a la mang chứa kết quả của phép trừ a - b còn mảng b là phep trừ của b - a .còn khi phep sosanh= 0 ta ko can tính và in ra ngay la số 0 ý tương nôm na có pải vậy ko bạn
Đúng rồi đó bạn.
Nình mới đọc lai bài bạn viết.dong lệnh mà bạn nói se nằm khi minh in mảng b ra hả bạn
Để mình đẩy bạn vào trọng tâm của bài này nhé. Bạn đọc kỹ lại thì sẽ thấy bài này không đơn giản thế. 2 số X và Y có thể âm, cũng có thể dương, bởi vậy tuy là tính hiệu nhưng mà cũng có thể tính tổng. Phần code ở bài khác chỉ để bạn tham khảo phương pháp làm. Bài này có nhiều trường hợp như là:
Mã:
Cùng dấu:
- 0 <= X <= Y.
- 0 <= Y <= X.
- X <= Y <= 0.
- Y <= X <= 0.
Khác dấu:
- X <= 0 <= Y.
- Y <= 0 <= X.
Bạn cần nghĩ thật kỹ xem: làm sao biểu diễn số âm, với mỗi trường hợp như trên thì kết quả tính thế nào, làm sao viết procedure tính tổng 2 số,... Ví dụ, thay vì mảng a và b từ 1..32001, thì chúng ta tăng thêm 0..32001 (hoặc là 1..32002) để lưu dấu cho 2 số X và Y. Với cách biểu diễn này thì chúng ta chỉ cần biết khi nào tính tổng, khi nào tính hiệu, số nào lớn hơn, và lấy số nào trừ cho số nào, để sau đó kết quả cuối cùng chúng ta biết chắc chắn đó phải là âm hay dương để lúc in ra thì có thêm dấu - hay không.
 
với trường hợp bạn nói xử lý số âm phải xử lý bằng bit hả bạn...thật thì mình cũng chưa nghĩ ra cáchđể lưu số âm thế nào
nếu nhiều trường hợp như thế mình phải có thêm thủ tục cộng nữa hả bạn
 
Sửa lần cuối:

tengiday

Happy life
với trường hợp bạn nói xử lý số âm phải xử lý bằng bit hả bạn...thật thì mình cũng chưa nghĩ ra cáchđể lưu số âm thế nào
nếu nhiều trường hợp như thế mình phải có thêm thủ tục cộng nữa hả bạn
Trên OS và nhiều compilers thì dùng bit để đánh dấu, nhưng chúng ta có thể đặt hẳn 1 biến shortint để làm việc này. Nếu bạn nhìn vào mấy trường hợp thì thấy: cùng dấu là phải trừ, khác dấu thì cộng. Như vậy, ví dụ nhé, nếu mình khai báo
Mã:
type numArr = array[0..32001] of shortint
với X[0] = 1 nếu X > 0 và -1 nếu X < 0, thì còn lại, |X| = 1..32001. Khi đó,
Mã:
Cùng dấu:
- 0 <= X <= Y. Kết quả X - Y = -(|Y| - |X|).
- 0 <= Y <= X. Kết quả X - Y = |X| - |Y|.
- X <= Y <= 0. Kết quả X - Y = -(|X| - |Y|).
- Y <= X <= 0. Kết quả X - Y = |Y| - |X|.
Khác dấu:
- X <= 0 <= Y. Kết quả X - Y = -(|X| + |Y|).
- Y <= 0 <= X. Kết quả X - Y = |X| + |Y|.
Tư tưởng của thủ tục cộng giống như của trừ, có thể dễ hơn trừ nữa bạn ạ. Bạn đã viết trừ rồi thì thấy nó y chang như trừ tay; bây giờ bạn thử viết cộng xem.

PS: Trước hết bạn làm phần cùng dấu trước đã, sau hãy làm phần khác dấu. Function compare là so sánh |X| và |Y| đấy. Code xử lý chung chung sẽ như thế này.
Mã:
if (a[0] > 0 and b[0] > 0) then   // X và Y cùng dương.
   begin
      t := compare(a, na, b, nb);
      if (t > 0) then   // |X| > |Y|
         begin
         end
      else if (t < 0) then   // |X| < |Y|
         begin
         end
      else ...
   end
else if (a[0] < 0 and b[0] < 0) then   // X và Y cùng âm.
   begin
      // xử lý tương tự
   end
else if (a[0] < 0 and 0 < b[0]) then   // X âm và Y dương.
   begin
      sum(a, na, b, nb); // cộng lại, kết quả lưu ở a.
      in kết quả -a.
   end
else   // trường hợp cuối X dương và Y âm.
   begin
      sum(a, na, b, nb); // cộng lại, kết quả lưu ở a.
      in kết quả a.
   end;
Những trường hợp đặc biệt như 0 hay input có mấy số 0 ở đầu thì bạn tự xử lý nhé.

Bài không khó lắm đâu bạn. Bài này theo khuynh hướng kỹ thuật lập trình. Bạn cố gắng làm nhé!

Good luck.
 
cảm ơn bạn các thủ tục mình cũng làm được phần nào rôi.ở đây thủ tục so sánh cũng giống ở trên phải ko bạn? chỉ cần thêm (|a| > |([b)| hay là như thế nào hả bạn/ mình còn phân vân cái này nữa
 
Sửa lần cuối:
Mình thấy bài ucln của bạn bên kia cũng hay nên mình có lấy text thử nhưng sao thấy bị lỗi
khi in ra thì chỉ in nguyên giá trị của mảng a. chứ chưa tính được ucln cua n, m so trên
nhờ bạn xem thử lỗi ở đâu vậy bạn phải chăng tại thủ thuc ucln bi loi j hay ko
const MAX = 32001;
fi = 'UC.INP';
fo = 'UC.OUT';
type numArray = array[1..MAX] of shortint;
var a, b : numArray;
n, m : integer;
f : text;




procedure doc;
var x : char;
i, so, code : integer;
begin
assign(f, fi); reset(f);
readln(f, n, m);
for i:=1 to MAX do begin a:=0; b:=0; end;
for i:=n downto 1 do
begin
read(f, x);
val(x, so, code);
a := so;
end;
readln(f);
for i:=m downto 1 do
begin
read(f, x);
val(x, so, code);
b := so;
end;
close(f);
end;




function SOSANH( VAR a: numArray; VAR n: integer; VAR b: numArray; VAR M: integer) : shortint;
var i : integer;
begin
if (N < M) then SOSANH:=-1;
if (n > M) then SOSANH:= 1;
for i := n downto 1 do
begin
if (a > b) then SOSANH:=1;
if (a < b) then SOSANH:=-1;
end;
SOSANH:=0;
end;




procedure differences(var a: numArray; var n: integer; VAR b: numArray; VAR M: integer);
var i, index : integer;
nho : shortint;
begin
nho := 0;
index := 1;
for i := 1 to N do
begin
if (a >= b + nho) then
begin
a := a - b - nho;
nho := 0;
end
else
begin
a := a + 10 - b - nho;
nho := 1;
end;
if (a > 0) then
index := i;
end;
n := index;
end;




procedure greatestCommonDivisor(var a: numArray; var n: integer; var b: numArray; var M: integer);
var t : shortint;
begin
t := SOSANH(a, n, b, M);
while (t <> 0) do
begin
if (t > 0) then
differences(a, n, b, M);
if (t < 0) then
differences(b, M, a, N);
t := SOSANH(a, n, b, M);
end;
end;




procedure xuat;
var i : integer;
begin
assign(f,fo); rewrite(f);
greatestCommonDivisor(a, n, b, m);
for i := n downto 1 do write(F,a);
close(f);
end;




begin
doc;


xuat;
end.
 

tengiday

Happy life
cảm ơn bạn các thủ tục mình cũng làm được phần nào rôi.ở đây thủ tục so sánh cũng giống ở trên phải ko bạn? chỉ cần thêm (|a| > |([b)| hay là như thế nào hả bạn/ mình còn phân vân cái này nữa

Cái a và b, 1 <= i <= 32001 lúc nào cũng dương. Đó là chữ số, chỉ có phần tử đầu tiên là báo âm hay dương thôi (theo như ví dụ của mình).
Ví dụ: số -32 đc biểu diễn là
a[0] = -1
a[1] = 2
a[2] = 3
Bạn xem kĩ hàm 'compare' sẽ thấy nó chỉ so sánh từ 1 trở đi thôi.

Về bài kia, bạn có thể in thử mảng 'a' và 'b' trong vòng while ra xem. Bạn dùng debug chạy từng dòng lệnh để xem nhé.
 

Thống kê

Chủ đề
100,656
Bài viết
467,423
Thành viên
339,831
Thành viên mới nhất
TuanShinhanbank
Top