Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

ملخص - المجموعات العامة

جزء من قسم البرمجة كائنية التوجه في رحلة GO على Coddy. الدرس 72 من 107.

challenge icon

التحدي

سهل

لنَبْنِ هيكل بيانات Queue عامًا يوضّح كل ما تعلّمته عن الأنواع العامة في Go! بخلاف المكدس (LIFO)، تتبع قائمة الانتظار ترتيب الداخل أولًا يخرج أولًا (FIFO): العنصر الأول الذي تتم إضافته هو أول عنصر تتم إزالته.

ستُنظّم شيفرتك عبر ملفين:

  • queue.go: عرّف مجموعة Queue العامة.

    أنشئ بنية عامة Queue[T any] تخزّن items داخليًا. يجب أن تدعم قائمة الانتظار العمليات التالية:

    • Enqueue(item T) - تضيف item إلى back في قائمة الانتظار
    • Dequeue() (T, bool) - تزيل item من front في قائمة الانتظار وتعيده، إلى جانب قيمة منطقية indicator على النجاح (أعد القيمة الصفرية وfalse إذا كانت قائمة الانتظار empty)
    • Peek() (T, bool) - تعيد item الموجود في front دون إزالته (بنمط الإرجاع نفسه المتّبع في Dequeue)
    • Size() int - تعيد number العناصر في قائمة الانتظار
    • IsEmpty() bool - تعيد true إذا لم تكن في قائمة الانتظار أي items

    أنشئ أيضًا function مُنشئة NewQueue[T any]() *Queue[T] تعيد pointer إلى قائمة انتظار empty initialized.

  • main.go: اعرض كيفية استخدام Queue مع أنواع مختلفة استنادًا إلى الإدخال.

    اقرأ type indicator (int أو string)، ثم اقرأ سلسلة من commands لتنفيذها على قائمة الانتظار. يوجد كل command في line مستقل:

    • enqueue [value] - أضف value إلى قائمة الانتظار
    • dequeue - أزل واطبع item الموجود في front (اطبع empty إذا كانت قائمة الانتظار empty)
    • peek - اطبع item الموجود في front دون إزالته (اطبع empty إذا كانت قائمة الانتظار empty)
    • size - اطبع Size الحالي

    اقرأ commands حتى تتلقى done.

ستُوفَّر المدخلات التالية:

  • Line 1: type indicator (int أو string)
  • Following lines: commands حتى done

على سبيل المثال، بالنظر إلى:

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

يجب أن يكون الناتج:

10
10
2
20
30
empty

وبالنظر إلى:

string
enqueue hello
enqueue world
size
peek
dequeue
peek
done

يجب أن يكون الناتج:

2
hello
hello
world

يجب أن تعمل Queue بالطريقة نفسها مع نوعي integer وstring، موضّحةً كيف يتعامل تنفيذ generic واحد مع أنواع concrete متعددة مع الحفاظ على type safety الكامل.

جرّب بنفسك

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// اقرأ مؤشر النوع
	scanner.Scan()
	typeIndicator := scanner.Text()
	
	if typeIndicator == "int" {
		// TODO: أنشئ طابور أعداد صحيحة باستخدام NewQueue[int]()
		// عالج الأوامر لطابور الأعداد الصحيحة
		
		for scanner.Scan() {
			line := scanner.Text()
			if line == "done" {
				break
			}
			
			parts := strings.SplitN(line, " ", 2)
			command := parts[0]
			
			// TODO: تعامل مع الأوامر: enqueue, dequeue, peek, size
			// بالنسبة لـ enqueue، حلّل قيمة العدد الصحيح من parts[1]
			// بالنسبة لـ dequeue/peek، اطبع "empty" إذا كان الطابور فارغًا
			_ = command
		}
	} else if typeIndicator == "string" {
		// TODO: أنشئ طابور سلاسل نصية باستخدام NewQueue[string]()
		// عالج الأوامر لطابور السلاسل النصية
		
		for scanner.Scan() {
			line := scanner.Text()
			if line == "done" {
				break
			}
			
			parts := strings.SplitN(line, " ", 2)
			command := parts[0]
			
			// TODO: تعامل مع الأوامر: enqueue, dequeue, peek, size
			// بالنسبة لـ enqueue، استخدم قيمة السلسلة النصية من parts[1]
			// بالنسبة لـ dequeue/peek، اطبع "empty" إذا كان الطابور فارغًا
			_ = command
		}
	}
	
	// هذه موجودة لتجنب أخطاء الاستيراد غير المستخدم أثناء التطوير
	_ = strconv.Atoi
	_ = fmt.Println
}

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Go عبر الإنترنت