Menu
CoddyTech

Tạo tập hợp

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 32 trên 68.

Giờ bạn đã hiểu ý tưởng đằng sau cách dùng set trong Go, đã đến lúc thực hành bằng cách tạo tập hợp đầu tiên. Cách làm rất đơn giản và theo cùng quy tắc bạn đã học với map.

Để tạo một tập hợp trong Go, bạn khai báo một biến bằng mẫu map[T]struct{}, trong đó T là kiểu dữ liệu của các phần tử bạn muốn lưu trữ. Sau đây là cách tạo một tập hợp để lưu trữ các tên màu duy nhất:

colors := make(map[string]struct{})

Bạn cũng có thể khởi tạo một tập hợp với một số giá trị ban đầu bằng cú pháp map literal:

colors := map[string]struct{}{
    "red":   {},
    "blue":  {},
    "green": {},
}

Lưu ý rằng mỗi giá trị đều là một giá trị cấu trúc rỗng {}. Giá trị này tạo ra giá trị không của struct{}, không chiếm bộ nhớ nhưng vẫn cho phép khóa tồn tại trong map.

Điểm hay của cách tiếp cận này là tận dụng cơ sở hạ tầng map sẵn có của Go, đồng thời mang lại ngữ nghĩa tập hợp thực sự: mỗi tên màu chỉ có thể xuất hiện một lần và bạn có thể tra cứu nhanh như với các map thông thường.

challenge icon

Thử thách

Dễ

Tạo một công cụ theo dõi ngôn ngữ lập trình yêu thích, minh họa cách dùng quy ước tập hợp (set) của Go để lưu các phần tử duy nhất. Thử thách này cho bạn thấy cách dùng mẫu map[string]struct{} để theo dõi các ngôn ngữ lập trình mà không bị trùng lặp.

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

  • Một chuỗi biểu thị số ngôn ngữ cần xử lý (ví dụ: "6")
  • Một chuỗi chứa các ngôn ngữ lập trình, phân tách bằng dấu phẩy (ví dụ: "Go,Python,JavaScript,Go,Java,Python,C++,JavaScript")

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

  1. Tạo một tập hợp bằng quy ước của Go map[string]struct{} để lưu các ngôn ngữ lập trình duy nhất
  2. Phân tích chuỗi đầu vào bằng cách tách chuỗi tại các dấu phẩy để lấy tên từng ngôn ngữ
  3. Thêm từng ngôn ngữ vào tập hợp bằng cách dùng giá trị cấu trúc rỗng {}
  4. Hiển thị kết quả xử lý bằng cách in ra từng ngôn ngữ khi gặp ngôn ngữ đó:
    • Nếu ngôn ngữ chưa có trong tập hợp: "Added: [language]"
    • Nếu ngôn ngữ đã có trong tập hợp: "Already exists: [language]"
  5. Sau khi xử lý tất cả ngôn ngữ, hiển thị phần tổng kết:
    • "Total languages processed: [total_count]"
    • "Unique languages: [unique_count]"
  6. Cuối cùng, liệt kê tất cả ngôn ngữ duy nhất trong tập hợp:
    • Tiêu đề: "Programming languages in set:"
    • Mỗi ngôn ngữ trên một dòng riêng: "- [language]"

Dùng gói strings để tách chuỗi đầu vào và gói strconv để chuyển chuỗi số lượng thành số nguyên. Để kiểm tra xem một ngôn ngữ đã có trong tập hợp hay chưa trước khi thêm, hãy dùng quy ước dấu phẩy ok: _, exists := languageSet[language]. Thử thách này cho thấy quy ước tập hợp của Go giúp theo dõi các phần tử duy nhất và ngăn dữ liệu bị trùng lặp một cách hiệu quả.

Tự làm thử

package main

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
)

func main() {
	// Đọc đầu vào
	var countStr string
	var languagesStr string
	fmt.Scanln(&countStr)
	fmt.Scanln(&languagesStr)
	
	// Chuyển chuỗi count thành số nguyên (không cần cho thử thách này)
	_, _ = strconv.Atoi(countStr)
	
	// Tách chuỗi languages theo dấu phẩy
	languages := strings.Split(languagesStr, ",")
	
	// Tạo tập hợp bằng cách dùng mẫu map[string]struct{}
	languageSet := make(map[string]struct{})
	
	// TODO: Viết code bên dưới
	// Xử lý từng ngôn ngữ và kiểm tra xem nó có trong tập hợp không
	// Dùng mẫu comma ok: _, exists := languageSet[language]
	// In ra "Added: [language]" hoặc "Already exists: [language]"
	// Thêm các ngôn ngữ vào tập hợp bằng giá trị struct rỗng {}
	
	// In ra thông tin tóm tắt
	// In ra tổng số ngôn ngữ đã xử lý và số ngôn ngữ không trùng lặp
	
	// In ra tất cả ngôn ngữ không trùng lặp trong tập hợp
	fmt.Println("Programming languages in set:")
	// Chuyển map thành slice rồi sắp xếp để đầu ra luôn theo cùng một thứ tự
	// Liệt kê từng ngôn ngữ theo định dạng "- [language]"
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

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