Giải Tin Học 10 trang 134

Lời giải chi tiết SGK Lớp 10 · Môn Tin Học · Trang 134–135

Nguon: Tin Hoc 10 - Ket Noi Tri Thuc Voi Cuoc Song (trang 134 – 135)

🔍 Kiến thức cần nhớ

  • Chương trình con (hàm) giúp chia một bài toán lớn thành nhiều bài toán nhỏ, làm chương trình chính rõ ràng, dễ hiểu, dễ bảo trì và nâng cấp.
  • Hàm có thể trả lại giá trị qua lệnh return, và nhận giá trị đầu vào qua các đối số (tham số).
  • Một số kĩ thuật quan trọng:
  • Gọi hàm khác bên trong chương trình chính (ví dụ dùng hàm prime(k) để kiểm tra số nguyên tố).
  • Dùng lệnh split(sep) để tách một xâu thành danh sách các từ theo kí tự tách sep.
  • Dùng len(list) để đếm số phần tử của danh sách.
💡 Mẹo nhớ: "Một hàm – một nhiệm vụ". Mỗi hàm chỉ nên làm tốt một việc, kết quả trả về bằng return.

⚙️ Bài tập (Câu hỏi trang 133)

Câu 1

Đề bài: Sử dụng hàm prime, em hãy viết chương trình in ra các số nguyên tố trong khoảng từ m đến n, với m, n là hai số tự nhiên và 1 < m < n.

Ta tận dụng lại hàm prime(k) đã định nghĩa ở phần trên (hàm trả về True nếu k là số nguyên tố). Chương trình chính chỉ cần nhập m, n rồi duyệt và in các số nguyên tố trong đoạn đó.

Cách 1 — Dùng lại hàm prime và vòng lặp for
def prime(C):
    if C < 2:
        return False
    k = 0
    for i in range(2, C):
        if C % i == 0:
            k = k + 1
    if k == 0:
        return True
    else:
        return False

# Chương trình chính
m = int(input("Nhập số tự nhiên m: "))
n = int(input("Nhập số tự nhiên n: "))

print("Các số nguyên tố từ", m, "đến", n, "là:")
for k in range(m, n + 1):
    if prime(k):
        print(k, end=" ")

Giải thích:

  • Vòng lặp for k in range(m, n + 1) duyệt qua tất cả số tự nhiên từ m đến n (kể cả n).
  • Mỗi số k được kiểm tra bằng prime(k). Nếu là số nguyên tố thì in ra trên cùng một dòng (nhờ end=" ").
Cách 2 — Kiểm tra số nguyên tố tối ưu (chỉ chia đến √C)

Một số nguyên C ≥ 2 là hợp số thì luôn có một ước nhỏ hơn hoặc bằng √C, nên ta chỉ cần kiểm tra các ước từ 2 đến √C. Cách này nhanh hơn nhiều khi n lớn.

def prime(C):
    if C < 2:
        return False
    i = 2
    while i * i <= C:
        if C % i == 0:
            return False
        i = i + 1
    return True

# Chương trình chính
m = int(input("Nhập số tự nhiên m: "))
n = int(input("Nhập số tự nhiên n: "))
for k in range(m, n + 1):
    if prime(k):
        print(k, end=" ")
⚠️ Lưu ý thi: Đề yêu cầu dùng lại hàm prime, vì vậy điểm mấu chốt là gọi prime(k) trong chương trình chính chứ không viết lại logic kiểm tra. Ngoài ra nhớ dùng range(m, n+1) để không bỏ sót số n.

Câu 2

Đề bài: Em hãy nêu một công việc/bài toán nào đó mà có thể sử dụng hàm để giải.

Có rất nhiều bài toán phù hợp để tách thành hàm. Một số ví dụ tiêu biểu:

  • Tính giai thừa n! — viết hàm giaithua(n) trả về tích 1 × 2 × ... × n. Dùng được nhiều lần khi tính tổ hợp, chỉnh hợp.
  • Tìm ước chung lớn nhất (UCLN) của hai số — viết hàm ucln(a, b), rồi dùng để rút gọn phân số.
  • Tính chu vi, diện tích hình tròn — viết hàm dientich(r)chuvi(r), gọi lại mỗi khi cần tính với bán kính khác nhau.
  • Đếm số nguyên âm trong một dãy số — viết hàm dem_am(A) nhận vào danh sách A.
  • Kiểm tra một số có phải số chính phương không — viết hàm chinh_phuong(x).

Lý do nên dùng hàm: công việc đó lặp lại nhiều lần với dữ liệu khác nhau, hoặc là một bước con trong bài toán lớn. Khi đó tách thành hàm giúp chương trình ngắn gọn, dễ kiểm thử và tái sử dụng.


⚙️ THỰC HÀNH — Truyền giá trị cho đối số của hàm

Nhiệm vụ 1

Đề bài: Thiết lập hàm f_sum(A, b) tính tổng các số của danh sách A theo quy định:

  • Nếu b = 0 thì tính tổng tất cả các số của A.
  • Nếu b khác 0 thì chỉ tính tổng các số dương của A.
Cách 1 — Theo gợi ý sách giáo khoa
def f_sum(A, b):
    S = 0
    for x in A:
        if b == 0:
            S = S + x
        else:
            if x > 0:
                S = S + x
    return S

# Kiểm tra thử
A = [0, 2, -1, 5, 10, -3]
print(f_sum(A, 0))   # Tính tổng tất cả -> 13
print(f_sum(A, 1))   # Chỉ tính số dương -> 17

Giải thích:

  • Biến đếm S khởi tạo bằng 0.
  • Với mỗi phần tử x trong A, ta kiểm tra giá trị của b:
  • b = 0: cộng mọi phần tử.
  • b ≠ 0: chỉ cộng khi x > 0.
Cách 2 — Rút gọn điều kiện bằng phép logic

Có thể gộp hai trường hợp bằng một điều kiện duy nhất: cộng x khi (b = 0) hoặc (x > 0).

def f_sum(A, b):
    S = 0
    for x in A:
        if b == 0 or x > 0:
            S = S + x
    return S
💡 Mẹo nhớ: Khi hai nhánh if/else chỉ khác nhau ở điều kiện cộng, hãy gộp lại bằng toán tử or/and cho gọn.

Nhiệm vụ 2

Đề bài: Thiết lập hàm f_dem(msg, sep) đếm số từ của một xâu msg với kí tự tách từ là sep.

Ví dụ:

  • f_dem("Mùa thu lịch sử", " ") trả lại giá trị 4.
  • f_dem("Mùa thu lịch sử", "-") trả lại giá trị 1.
Cách 1 — Dùng split() và len() theo hướng dẫn
def f_dem(msg, sep):
    xlist = msg.split(sep)
    return len(xlist)

# Kiểm tra thử
print(f_dem("Mùa thu lịch sử", " "))   # 4
print(f_dem("Mùa thu lịch sử", "-"))   # 1

Giải thích:

  • msg.split(sep) cắt xâu msg tại mỗi vị trí xuất hiện kí tự sep, kết quả là một danh sách các từ.
  • Với dấu cách " ": "Mùa thu lịch sử" tách thành ["Mùa", "thu", "lịch", "sử"] → có 4 từ.
  • Với dấu "-": trong xâu không có dấu "-" nên split trả về cả xâu thành 1 phần tử → 1 từ.
  • len(xlist) đếm số phần tử của danh sách, chính là số từ.
Cách 2 — Đếm trực tiếp không cần biến trung gian
def f_dem(msg, sep):
    return len(msg.split(sep))
⚠️ Lưu ý thi: split(sep) cắt theo đúng kí tự sep đã chỉ định. Nếu trong xâu không xuất hiện sep, kết quả là danh sách 1 phần tử (cả xâu), nên hàm trả về 1 chứ không phải 0.

Nhiệm vụ 3

Đề bài: Thiết lập hàm merge_str(s1, s2) với s1, s2 là hai xâu cần gộp.

Hàm gộp hai xâu bằng cách lấy lần lượt từng kí tự của s1, s2 đưa vào xâu kết quả. Nếu một xâu hết kí tự thì đưa phần còn lại của xâu dài hơn vào xâu kết quả.

Ví dụ: s1 = "1111", s2 = "0000" thì xâu kết quả là "10101010".

Cách 1 — Duyệt theo chỉ số, xử lý phần dư bằng cắt xâu
def merge_str(s1, s2):
    kq = ""
    n = min(len(s1), len(s2))
    # Ghép xen kẽ phần chung
    for i in range(n):
        kq = kq + s1[i] + s2[i]
    # Đưa phần còn lại của xâu dài hơn vào kết quả
    kq = kq + s1[n:] + s2[n:]
    return kq

# Kiểm tra thử
print(merge_str("1111", "0000"))     # 10101010
print(merge_str("123", "abcdef"))    # 1a2b3cdef

Giải thích:

  • n = min(len(s1), len(s2)) là số kí tự được ghép xen kẽ (đến khi xâu ngắn hơn hết).
  • Vòng for ghép lần lượt s1[i] rồi s2[i].
  • Sau đó s1[n:]s2[n:] lấy phần dư: một trong hai sẽ là xâu rỗng, phần còn lại là đoạn dư của xâu dài hơn. Cộng cả hai vào là gọn nhất.
Cách 2 — Dùng vòng while và biến chỉ số
def merge_str(s1, s2):
    kq = ""
    i = 0
    # Ghép xen kẽ khi cả hai xâu còn kí tự
    while i < len(s1) and i < len(s2):
        kq = kq + s1[i] + s2[i]
        i = i + 1
    # Thêm phần còn lại
    while i < len(s1):
        kq = kq + s1[i]
        i = i + 1
    while i < len(s2):
        kq = kq + s2[i]
        i = i + 1
    return kq

print(merge_str("1111", "0000"))   # 10101010
💡 Mẹo nhớ: Bài "gộp xen kẽ hai xâu" có 2 giai đoạn: (1) ghép xen kẽ phần chung đến độ dài xâu ngắn hơn, (2) thêm phần dư của xâu dài hơn. Nhớ đủ 2 bước thì không bị mất kí tự.

🎯 Ghi nhớ: - Hàm giúp tái sử dụng logic (như prime, tongduong) và làm chương trình chính rõ ràng. - Truyền đối số cho phép một hàm xử lý linh hoạt theo dữ liệu vào (như f_sum(A, b) đổi cách tính theo b). - split(sep) + len() là cặp công cụ kinh điển để đếm số từ. - Khi gộp/ghép hai dãy hoặc hai xâu, luôn nhớ xử lý phần dư của đối tượng dài hơn.
Chế độ đọc sách →