Xin chào các bạn,
Mình có theo dõi tin mạng và có đọc được một bài viết rất dễ thương về một anh chàng bị cô người yêu bắt phải xin lỗi 200 lần với điều kiện cả 200 lần đó phải khác nhau.
Nói về mặt tình cảm và xã hội thì đơn thuần mình thấy cách xử lý của cô này rất dễ thương và việc dễ thương hơn nữa khi mà anh này chấp nhận hạ cái tôi của một đứa con trai để đáp ứng yêu sách của cô ấy.
Luận bàn chơi thôi chứ trở lại vấn đề, đó là dựa vào bài viết xã hội đó, mình suy nghĩ tới một ý tưởng tạo ra một giái pháp tiết kiệm thời gian cho anh ta. Vì vậy bài toán đặt ra là: làm sao để làm một chương trình viết dùm mình 200 lần xin lỗi mà câu từ không trùng nhau? Đó cũng là chủ đề chính của bài viết này ^^
Chúng ta cùng xem xét điều kiện của bài toán như sau:
- Tự động viết >= 200 lần xin lỗi
- Không được giống nhau ở mỗi lần
Bắt đầu lên ý tưởng, mình thấy rằng, các câu từ như: "mình xin lỗi bạn", "anh rất xin lỗi em", "anh xin lỗi bé",... đều mang một cấu trúc chung là:
- Phần chủ ngữ: tôi, mình, anh, chồng, tớ,...
- Phần xin lỗi: xin lỗi, rất xin lỗi, ngàn lần xin lỗi, cúi đầu xin lỗi,...
- Phần đối tượng: bạn, em, bé, vợ, cậu,...
Như vậy mình chỉ cần làm một thuật toán mà có thể liệt kê các phần trên lại với nhau với điều kiện thứ tự liệt kê không được lặp lại để tạo nên các câu từ khác nhau.
Đầu tiên, để ghép nối các từ lại với nhau thành câu, mình sẽ lưu các từ trên vào một mảng hai chiều, trong đó chiều 1 sẽ tượng trưng cho thứ tự phần và chiều 2 sẽ tượng trưng cho thứ từ các từ trong phần.
Như vậy, để tạo thành một câu ngẫu nhiên, chúng ta chỉ cần ghép nối các phần lại với nhau như sau:
Nhưng có điều, chúng ta không tạo theo cách ngẫu nhiên được vì câu có thể trùng nhau, mà chúng ta phải tạo câu theo một quy tắc nào đó để tận dụng hết các từ trong phần để tạo nên những câu khác nhau.
Bạn cứ tạm suy nghĩ vài phút trước khi xem tiếp nhé ^^
Tiếp tục nhé, đầu tiên mình sẽ khai báo các mảng.
Mình sẽ lên ý tưởng là: mình sẽ cho chạy 3 vòng lặp, xuất từ các ký tự trong mảng theo thứ tự phần.
Nhưng sẽ có vấn đề xảy ra, đó là chúng ta giải quyết được vấn đề khi chúng ta giả dụ tình huống là 3 phần, lỡ rằng người dùng nhập 4 phần, 5 phần hoặc n phần thì sẽ như thế nào?
Chúng ta phải giải quyết vấn đề một cách tổng thể là liệt kê các chuỗi ký tự theo một trật tự nhất định (chứ không phải xáo trộn) và mình có 2 cách giải quyết, về cơ bản và nâng cao.
Cách cơ bản, ý tưởng của mình sẽ duyệt từ phần 1 tới phần n, xuất từng từ của các phần theo một thứ tự cho tới khi không còn thứ tự nào nữa.
Cách nâng cao hơn, mình sử dụng theo ý tưởng đệ quy và chỉ cần gọi hàm ra là xong ^^. Về đệ quy thì tương lai mình sẽ viết 1 chuyên mục riêng để các bạn hiểu rõ hơn về phần này.
Vậy là chúng ta đã giải quyết xong vấn đề liệt kê các ký tự để tạo thành câu. Vấn đề tiếp theo là đạt đủ 200 câu. Theo thuật toán thì chúng ta có công thức:
Tổng số câu = Tích của tổng phần tử các phầnVí dụ bài toán trên, với code trên thì tôi có:
Tổng số câu = 2 (tổng phần tử phần 1) * 2 (tổng phần tử phần 2) * 2 (tổng phần tử phần 3) = 8 câuVậy để đạt 200 câu và với tình huống này, mình tạo 4 phần (phần ngôi xưng bản thân, phần động từ xin lỗi, phần ngôi xưng đối tượng và phần cảm thán)
- Phần 1 (5 phần tử): anh, tôi, tớ, chồng, mình
- Phần 2 (8 phần tử): xin lỗi, rất xin lỗi, vô cùng xin lỗi, thực sự xin lỗi, cúi đầu xin lỗi, dập gối xin lỗi, ngàn lần xin lỗi, trăm lần xin lỗi
- Phần 3 (5 phần tử): em, vợ, cậu, cưng, bé
- Phần 4 (4 phần tử): nha, nhiều, mà, yêu
Vậy tổng số câu tôi có là: 5*8*5*4 = 800 câu, vượt 4 lần chỉ tiêu người ấy đề ra ^^
Thế là giải quyết xong vấn đề tổng thể của bài toán ^^. Tuy nhiên vẫn còn một số vấn đề liên quan tới ngôi xưng chẳng hạn, mình để lại cho các bạn thảo luận và giải quyết ^^
Nếu bạn nào có cách giải khác hay, mong các bạn chia sẻ ở mục comment bên dưới.
7 nhận xét
nhận xéttuyệt vời (y)
Replynhức đầu -_-
Replyđã cố gắn trình bày bằng cách dễ hiểu nhất :D
ReplyNếu làm như trên thì sẽ ra mấy câu đại loại như "tớ xin lỗi vợ lắm", "anh xin lỗi cậu yêu",... Nên mình nghĩ là làm như sau:
Reply- B1: Tạo 4 dãy biến 1 chiều, mỗi biến là 1 từ (như cách chia 4 phần như trên)
- B2: Do chỉ có 1 số ngôi xưng kết hợp với nhau được nên ta sẽ làm 1 list thủ công những cách kết hợp giữ 2 ngôi xưng cho phù hợp
vd: với (mảng 1) tớ = 1, mình = 2, chồng = 3
(mảng 3) vợ = 1, cậu = 2, bạn = 3
Vậy những cách kết hợp đúng là: 12, 22, 23, 31
Lưu các giá trị này vào dãy 1 chiều (mảng 5)
B3: Kết hợp từng biến thuộc mảng 2,4,5 rồi gắn với nhau thành câu hoàn chỉnh
vd: (mảng 2) xin lỗi = 1, thật sự xin lỗi = 2
(mảng 4) nhiều = 1, nhìu = 2, lắm = 3
với (M2,4,5) = (1,1,1) => câu = "xin lỗi" + "nhiều" + (M5 có giá trị 1)
= M1(1) + "xin lỗi" + M3(2) + "nhiều"
= tớ + xin lỗi + cậu + nhiều
Cách làm này sẽ cho được ít câu hơn, nhưng các câu đúng ngữ pháp hơn
tùy trường hợp mà bạn có thể thay đổi ngôi xưng ở mỗi cột ^^ thuật toán này áp dụng cho cả n cột và vì vậy việc sắp đặt văn từ phụ thuộc rất nhiều ở người dùng ^^
Replytks b vì ý kiến đóng góp này, nếu viết chuyên về một phần mềm random thành câu tiếng Việt thì giải pháp của b là giải pháp rất tốt vì tính logic của văn từ được chuẩn mực hơn ^^
(y)
giờ mới nhận ra não mình nó bị teo cmnl =.="
Replynó thuộc về tư duy lập trình ^^
Reply