Menu
CoddyTech

Ôn tập: bộ đếm tần suất từ

Thuộc phần Logic và luồng điều khiển trong hành trình GO của Coddy. Bài học 30 trên 68.

challenge icon

Thử thách

Dễ

Xây dựng một công cụ phân tích văn bản để đếm tần suất xuất hiện của các từ trong tài liệu. Thử thách này cho thấy map rất hữu ích khi tổng hợp dữ liệu bằng cách theo dõi số lần mỗi từ riêng biệt xuất hiện trong một đoạn văn bản.

Bạn sẽ nhận hai đầu vào:

  • Một chuỗi văn bản cần phân tích (ví dụ: "the quick brown fox jumps over the lazy dog the fox is quick")
  • Một chuỗi biểu thị ngưỡng tần suất tối thiểu (ví dụ: "2")

Quan trọng: Văn bản đầu vào có thể chứa dấu cách, vì vậy bạn phải đọc toàn bộ dòng bằng bufio.NewReader với ReadString('\n') hoặc dùng bufio.Scanner: không dùng fmt.Scanln để đọc văn bản đầu vào, vì hàm này ngừng đọc khi gặp dấu cách đầu tiên.

Nhiệm vụ của bạn là:

  1. Tạo một hàm có tên countWords nhận một chuỗi văn bản và trả về một map[string]int, trong đó:
    • Các khóa là những từ riêng lẻ (chuỗi)
    • Các giá trị là số lần mỗi từ xuất hiện (số nguyên)
  2. Phân tích văn bản đầu vào bằng cách tách văn bản thành các từ riêng lẻ bằng strings.Fields (hàm này tách theo mọi khoảng trắng)
  3. Đếm tần suất xuất hiện của mỗi từ trong văn bản:
    • Chuyển tất cả các từ thành chữ thường để đếm nhất quán
    • Với mỗi từ, tăng số đếm của từ đó trong map lên 1
    • Nếu một từ chưa có trong map, giá trị ban đầu của từ đó sẽ là 0 và được tăng lên 1
  4. Lọc kết quả để chỉ hiển thị những từ xuất hiện ít nhất bằng số lần theo ngưỡng
  5. Hiển thị kết quả theo định dạng sau:
    • Tiêu đề: "Word Frequency Analysis:"
    • Với mỗi từ đạt ngưỡng: "[word]: [count]"
    • Hiển thị các từ theo thứ tự bảng chữ cái
  6. Tính và hiển thị số liệu thống kê tổng hợp:
    • "Total unique words: [total_unique_count]"
    • "Words above threshold: [filtered_count]"
    • "Most frequent word: [word] ([count] times)"
    • Nếu nhiều từ có cùng số lần xuất hiện cao nhất, hãy báo cáo từ đứng trước theo thứ tự bảng chữ cái. Nếu mỗi từ chỉ xuất hiện một lần, đó đơn giản là từ đầu tiên trong danh sách đã sắp xếp.

Ví dụ, với văn bản đầu vào "hello hello world" và ngưỡng "2", đầu ra sẽ là:

Word Frequency Analysis:
hello: 2
Total unique words: 2
Words above threshold: 1
Most frequent word: hello (2 times)

Dùng package bufio để đọc toàn bộ các dòng đầu vào, package strings để tách văn bản và chuyển thành chữ thường, package strconv để chuyển chuỗi ngưỡng thành số nguyên, và package sort để sắp xếp các từ theo thứ tự bảng chữ cái. Thử thách này cho thấy map là một giải pháp hiệu quả để đếm và tổng hợp dữ liệu, đồng thời cách map hoạt động với giá trị mặc định bằng 0 giúp logic đếm đơn giản và hiệu quả.

Tự làm thử

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)

	// Đọc toàn bộ dòng văn bản (kể cả dấu cách)
	scanner.Scan()
	text := scanner.Text()

	// Đọc giá trị ngưỡng
	scanner.Scan()
	thresholdStr := scanner.Text()

	// Chuyển threshold thành số nguyên
	threshold, _ := strconv.Atoi(thresholdStr)

	// TODO: Viết code của bạn bên dưới
	// 1. Tạo hàm (function) countWords trả về map[string]int
	//    Gợi ý: dùng strings.Fields và strings.ToLower để tách và chuẩn hóa các từ
	// 2. Dùng hàm để đếm số lần xuất hiện của từng từ
	// 3. Lọc các từ xuất hiện ít nhất 'threshold' lần
	// 4. Sắp xếp các từ đã lọc theo thứ tự bảng chữ cái và hiển thị chúng
	// 5. Tính và hiển thị các số liệu thống kê tổng hợp

	_ = text
	_ = threshold
	fmt.Println("Word Frequency Analysis:")
}

Tất cả bài học trong Logic và luồng điều khiển

Tự luyện tập: Trình biên dịch Go online