Menu
CoddyTech

Ôn tập: tập hợp tổng quát

Thuộc phần Lập trình hướng đối tượng trong hành trình GO của Coddy. Bài học 72 trên 107.

challenge icon

Thử thách

Dễ

Hãy xây dựng một cấu trúc dữ liệu Queue tổng quát để minh họa tất cả những gì bạn đã học về kiểu tổng quát trong Go! Khác với ngăn xếp (LIFO), hàng đợi tuân theo thứ tự vào trước, ra trước (FIFO): phần tử được thêm vào đầu tiên sẽ là phần tử được lấy ra đầu tiên.

Bạn sẽ tổ chức code trong hai tệp:

  • queue.go: Định nghĩa bộ sưu tập hàng đợi tổng quát.

    Tạo một struct tổng quát Queue[T any] lưu trữ các phần tử bên trong. Hàng đợi của bạn cần hỗ trợ các thao tác sau:

    • Enqueue(item T) - thêm một phần tử vào cuối hàng đợi
    • Dequeue() (T, bool) - xóa và trả về phần tử ở đầu hàng đợi, kèm theo một giá trị boolean cho biết thao tác có thành công hay không (trả về giá trị 0 và false nếu hàng đợi trống)
    • Peek() (T, bool) - trả về phần tử ở đầu hàng đợi mà không xóa phần tử đó (cách trả về giống như Dequeue)
    • Size() int - trả về số lượng phần tử trong hàng đợi
    • IsEmpty() bool - trả về true nếu hàng đợi không có phần tử nào

    Đồng thời, tạo một hàm khởi tạo NewQueue[T any]() *Queue[T] trả về con trỏ đến một hàng đợi trống đã được khởi tạo.

  • main.go: Minh họa hàng đợi của bạn với các kiểu dữ liệu khác nhau, dựa trên đầu vào.

    Đọc một chỉ báo kiểu dữ liệu (int hoặc string), sau đó đọc một loạt lệnh để thực hiện trên hàng đợi. Mỗi lệnh nằm trên một dòng riêng:

    • enqueue [value] - thêm giá trị vào hàng đợi
    • dequeue - xóa và in ra phần tử ở đầu hàng đợi (in ra empty nếu hàng đợi trống)
    • peek - in ra phần tử ở đầu hàng đợi mà không xóa phần tử đó (in ra empty nếu hàng đợi trống)
    • size - in ra kích thước hiện tại

    Đọc các lệnh cho đến khi nhận được done.

Đầu vào sẽ có dạng như sau:

  • Dòng 1: Chỉ báo kiểu dữ liệu (int hoặc string)
  • Các dòng tiếp theo: Lệnh cho đến khi gặp done

Ví dụ, với đầu vào:

int
enqueue 10
enqueue 20
enqueue 30
peek
dequeue
size
dequeue
dequeue
dequeue
done

Đầu ra của bạn sẽ là:

10
10
2
20
30
empty

Với đầu vào:

string
enqueue hello
enqueue world
size
peek
dequeue
peek
done

Đầu ra của bạn sẽ là:

2
hello
hello
world

Hàng đợi của bạn cần hoạt động giống hệt nhau với cả kiểu số nguyên và kiểu chuỗi, qua đó cho thấy một cách triển khai tổng quát có thể xử lý nhiều kiểu cụ thể trong khi vẫn đảm bảo an toàn kiểu dữ liệu.

Tự làm thử

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Đọc chỉ báo kiểu dữ liệu
	scanner.Scan()
	typeIndicator := scanner.Text()
	
	if typeIndicator == "int" {
		// TODO: Tạo hàng đợi số nguyên bằng NewQueue[int]()
		// Xử lý các lệnh cho hàng đợi số nguyên
		
		for scanner.Scan() {
			line := scanner.Text()
			if line == "done" {
				break
			}
			
			parts := strings.SplitN(line, " ", 2)
			command := parts[0]
			
			// TODO: Xử lý các lệnh: enqueue, dequeue, peek, size
			// Với enqueue, chuyển giá trị từ parts[1] thành số nguyên
			// Với dequeue/peek, in ra "empty" nếu hàng đợi trống
			_ = command
		}
	} else if typeIndicator == "string" {
		// TODO: Tạo hàng đợi chuỗi bằng NewQueue[string]()
		// Xử lý các lệnh cho hàng đợi chuỗi
		
		for scanner.Scan() {
			line := scanner.Text()
			if line == "done" {
				break
			}
			
			parts := strings.SplitN(line, " ", 2)
			command := parts[0]
			
			// TODO: Xử lý các lệnh: enqueue, dequeue, peek, size
			// Với enqueue, dùng giá trị chuỗi từ parts[1]
			// Với dequeue/peek, in ra "empty" nếu hàng đợi trống
			_ = command
		}
	}
	
	// Các dòng này giúp tránh lỗi import không được sử dụng trong quá trình phát triển
	_ = strconv.Atoi
	_ = fmt.Println
}

Tất cả bài học trong Lập trình hướng đối tượng

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