Lập trình C++ Các thao tác trên ngày tháng [Archive] – Cộng đồng C Việt

View Full Version : Lập trình C++ Các thao tác trên ngày tháng

ALone_Onestar

Nhập vào ngày tháng năm. Viết các hàm tăng lên, giảm đi n tháng hoặc n ngày. Mình làm rồi mà thấy rối với nhiều trường hợp quá, ai biết có thể giúp mình được không ạ ?
Để giải quyết bài toán này, bạn cần xây dựng 1 truct date (gồm 3 trường ngày tháng năm) và có thể định nghĩa 1 số hàm của struct như sau:
1. Hàm kiểm tra năm nhuận (bool laNamNhuan(struct date)): dựa vào giá trị năm để xác định năm đấy có phải năm nhuận hay không
2. Hàm lấy số ngày trong tháng (int soNgayTrongThang(struct date)): dựa vào giá trị tháng và năm để xác định số ngày trong tháng (năm nhuận thì tháng 2 có 29 ngày và ngược lại thì 28 ngày)
3. Hàm lấy tháng kế tiếp (struct date thangKeTiep(struct date)): hàm này trả về 1 kiểu truct date nhưng chúng ta chỉ quan tâm giá trị của cặp (tháng, năm) trong giá trị trả về. Nếu tháng hiện tại là 12/2015 thì thấng kế tiếp là 1/2016
4. Hàm tăng lên n tháng:
Bạn cần xác định số tháng còn lại trong năm, ví dụ là m, khi đó (m = 12 – tháng hiện tại).
Nếu n<m (nghĩa là số tháng cần tăng bé hơn số tháng còn lại trong năm) thì vấn đề đơn giản, cộng số tháng và đưa ra kết quả.
Nếu n>m, thì ta tăng số năm lên 1 (date.year = date.year +1) và số tháng cần tăng còn lại n1 = n – m.
Tiếp theo đó, ta quy đổi từ số tháng cần tăng còn lại thành số năm: số năm cần tăng yy= n1/12 và số tháng tại thời điểm sau n tháng sẽ là mm = n1%12 (n1 mod 12).
Đưa ra đc kết quả cuôi cùng: date.year = date.year + yy, date.month = mm
5. Hàm tăng n ngày:
Dựa vào hàm lấy số ngày trong tháng, lấy số ngày trong tháng hiện tại là k.
Nếu (n + date.day) < k thì không vấn đê gì để nói (date.day là ngày hiện tại)
Ngược lai, nếu (n +date.day > k) thì nghĩa là số ngày cần tăng sẽ nhảy qua các tháng tiếp theo, nên cần xử lý tiếp.
Làm tuơng tự như hàm tăng n năm, chúng ta đưa ngày hiện tại về ngày cuối tháng và tính số ngày cần tăng còn lại.
Số ngày cần tăng còn lại n1 = n1 – (k – date.day) (trừ đi số ngày còn lại trong tháng)
ngày hiện tại: date.day = k; (đưa về cuối tháng)
Sau đó sử dụng 1 vòng while để kiểm tra số ngày cần tăng còn lại

while (n1 > 0)
Vì n1 > 0 nên chắc chắn phải nhảy qua tháng kế tiếp (do ngày hiện tại đã là ngày cuối cùng trong tháng), vậy nên tá sẽ tăng số tháng lên 1
date = thangKeTiep(date).
Lấy số ngày trong tháng tiếp theo (chính là tháng hiện tại sau khi tăng ở bước trên): k1 = soNgayTrongThang(date).
nếu (n1 >= k1) – nghĩa là số ngày cần tăng lớn hơn hoặc bằng số ngày của tháng kế tiếp thì ta sẽ giảm n1 đi và gán lại giá trị ngày
n1 = n1 – k1; date.day = k1 (= ngày cuối tháng)
nếu (n1 < k1) – thì ta gán lại số ngày và trả n1 lại bằng 0 để kết thúc vòng lặp
n1 = 0, date.day = n1;
——
Trên đây chỉ là giải thuật cho trường hợp tăng n tháng và tăng n ngày, bạn sẽ cần làm tương tự cho giảm n tháng và giảm n ngày (nếu sử dụng tuơng tự thì bạn sẽ cần thêm hàm tính tháng trước đấy thangTruocDo(struct date) chẳng hạn )
————
* Ngoài cách tiếp cận bên trên, còn 1 cách tiếp cạnh đơn giản khác là sử dụng 1 vòng lặp để giải quyết bài toán này, ví dụ:

for (i = 1 -> n) (n là số tháng)
{
date = thangKeTiep();
}

for (i = 1 -> n) (n là số ngày)
{
date = ngayKeTiep();
}

Tuơng tự cho việc giảm n tháng, giảm n ngày.
Tất nhiên để xây dựng các hàm ngayKeTiep() hay thangKeTiep() bạn cũng cần xây dựng 1 số hàm khác như soNgayTrongThang() hoặc laNamNhuan().
————–
Kết luận:
Đối vs n lớn thì cách tiếp cận đầu tiên sẽ xử lý nhanh hơn, tuy nhiên cách tiếp cận thì 2 thì dễ xử lý hơn.
————–
Mình ko có time để viết code, mong bạn thông cảm! 🙂 Tuy nhiên, việc tự viết code sẽ giúp bạn tự rèn luyện kỹ năng coding của mình tốt hơn.
Chúc may mắn.