C# Stack مع أمثلة Push & Pop

⚡ ملخص ذكي

Stack في لغة C# عبارة عن مجموعة من مساحة اسم System.Collections تتبع مبدأ LIFO (آخر ما يدخل، أول ما يخرج)، حيث تضيف طريقة Push عنصرًا إلى الأعلى وتقوم طريقة Pop بإزالته.

  • 📚 مفهوم LIFO: تعمل المكدسة مثل كومة من الكتب، لذا فإن آخر عنصر يتم دفعه هو أول عنصر يتم إزالته.
  • ادفع واسحب: تقوم طريقة Push بإضافة عنصر إلى أعلى المكدس، وتقوم طريقة Pop بإزالة وإرجاع ذلك العنصر العلوي.
  • ؟؟؟؟ ألقِ نظرة خاطفة، عد، يحتوي على: تقوم طريقة Peek بقراءة العنصر العلوي دون إزالته، بينما تقوم طريقتي Count و Contains بالإبلاغ عن الحجم والعضوية.
  • 🧪 أمثلة تطبيقية: يُظهر برنامجان يعملان عبر سطر الأوامر عملية الدفع باستخدام العد والاحتواء، ثم عملية السحب، حتى تتمكن من trace ترتيب LIFO.
  • 🛠️ مجموعة عامة: المكدس يُضيف الصنف الموجود في System.Collections.Generic أمانًا لأنواع البيانات في وقت الترجمة ويتجنب التغليف لرمز C# الجديد.
  • 🤖 مساعدة الذكاء الاصطناعي: يقوم GitHub Copilot بإنشاء عمليات C# Stack، ويقرأ ML.NET البيانات من خلال مجموعات مكتوبة بدلاً من مكدس غير عام.

C # المكدس

ما هو المكدس في C#؟

المكدس عبارة عن مجموعة حالات خاصة تمثل مفهوم ما يدخل أخيرًا يخرج أولاً (LIFO). لفهم LIFO أولاً، لنأخذ مثالاً. تخيل كومة من الكتب مع وضع كل كتاب فوق بعضها البعض.

ويعني مفهوم "ما يدخل أخيرًا يخرج أولاً" في حالة الكتب أنه لا يمكن إزالة سوى أعلى الكتب من مجموعة الكتب. لا يمكن إزالة كتاب من بينهما، لأن ذلك من شأنه أن يزعج إعداد المكدس.

وبالتالي في C#تعمل المكدسات أيضًا بنفس الطريقة. تتم إضافة العناصر إلى المكدس، واحدًا فوق الآخر. تسمى عملية إضافة عنصر إلى المكدس عملية الدفع. لإزالة عنصر من المكدس، يمكنك أيضًا إزالة العنصر العلوي في المكدس. تُعرف هذه العملية باسم pop.

دعونا نلقي نظرة على العمليات المتاحة لمجموعة Stack بمزيد من التفصيل.

إعلان المكدس

يتم إنشاء المكدس بمساعدة نوع Stack Data. يتم استخدام الكلمة الأساسية "جديد" لإنشاء كائن في المكدس. ثم يتم تعيين الكائن إلى المتغير st.

Stack st = new Stack()

إضافة عناصر إلى المكدس

يتم استخدام طريقة الدفع لإضافة عنصر إلى المكدس. ويرد أدناه بناء الجملة العام للبيان.

Stack.push(element)

إزالة العناصر من المكدس

تُستخدم طريقة pop لإزالة عنصر من المكدس. ستعيد عملية pop العنصر الأعلى في المكدس. يتم تقديم الصيغة العامة للبيان أدناه

 Stack.pop()

العد التنازلي

تُستخدم هذه الخاصية لمعرفة عدد العناصر الموجودة في المكدس. وفيما يلي بناء الجملة العام لهذا البيان.

Stack.Count

يحتوي

تُستخدم هذه الطريقة لمعرفة ما إذا كان هناك عنصر موجود في المكدس. وفيما يلي بناء الجملة العام لهذا البيان. سترجع العبارة صحيحًا إذا كان العنصر موجودًا، وإلا فسوف تُرجع القيمة خطأ.

Stack.Contains(element)

الآن دعونا نرى هذا يعمل على مستوى الكود. سيتم كتابة كافة التعليمات البرمجية المذكورة أدناه لدينا تطبيق وحدة التحكم. ستتم كتابة الكود في ملف Program.cs الخاص بنا.

في البرنامج أدناه، سنكتب الكود لنرى كيف يمكننا استخدام الطرق المذكورة أعلاه.

مثال 1: طريقة Stack.Push()

في هذا المثال سنرى

  • كيف يتم إنشاء المكدس.
  • كيفية عرض عناصر المكدس واستخدام طريقتي Count وContain.

المكدس في C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Stack st = new Stack();
   st.Push(1);
   st.Push(2);
   st.Push(3);

   foreach (Object obj in st)
   {
    Console.WriteLine(obj);
   }
    Console.WriteLine(); Console.WriteLine();
    Console.WriteLine("The number of elements in the stack " +st.Count);
    Console.WriteLine("Does the stack contain the elements 3 "+st.Contains(3));
    Console.ReadKey();
  }
 }
}

Code تفسير:-

  1. يتم استخدام الخطوة الأولى للإعلان عن المكدس. نحن هنا نعلن عن "st" كمتغير للاحتفاظ بعناصر مجموعتنا.
  2. بعد ذلك، نضيف 3 عناصر إلى مجموعتنا. تتم إضافة كل عنصر عبر طريقة الدفع.
  3. الآن نظرًا لأنه لا يمكن الوصول إلى عناصر المكدس عبر موضع الفهرس مثل قائمة المصفوفةنحتاج إلى استخدام طريقة مختلفة لعرض عناصر المكدس. الكائن (obj) هو متغير مؤقت، تم الإعلان عنه للاحتفاظ بكل عنصر من عناصر المكدس. نستخدم بعد ذلك عبارة foreach لتصفح كل عنصر من عناصر المكدس. لكل عنصر مكدس، يتم تعيين القيمة لمتغير obj. نستخدم بعد ذلك الأمر Console.Writeline لعرض القيمة على وحدة التحكم.
  4. نحن نستخدم خاصية العد (st.count) للحصول على عدد العناصر الموجودة في المكدس. ستُرجع هذه الخاصية رقمًا. ثم نعرض هذه القيمة على وحدة التحكم.
  5. نستخدم بعد ذلك طريقة الاحتواء لمعرفة ما إذا كانت القيمة 3 موجودة في مجموعتنا. سيعود هذا إما بقيمة صحيحة أو خاطئة. نقوم بعد ذلك بعرض قيمة الإرجاع هذه على وحدة التحكم.

إذا تم إدخال الكود أعلاه بشكل صحيح وتم تشغيل البرنامج، فسيتم عرض الإخراج التالي.

الإخراج:

المكدس في C#

من الناتج، يمكننا أن نرى أن عناصر المكدس معروضة. كما يتم عرض قيمة True للإشارة إلى أن القيمة 3 محددة في المكدس.

ملاحظات:لقد لاحظت أن آخر عنصر تم دفعه إلى المكدس يتم عرضه أولاً. هذا هو العنصر الأعلى في المكدس. كما يظهر عدد عناصر المكدس في الإخراج.

المثال 2: طريقة Stack.Pop()

الآن دعونا نلقي نظرة على وظيفة "الإزالة". سنرى الكود المطلوب لإزالة العنصر العلوي من المكدس.

المكدس في C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Stack st = new Stack();
   st.Push(1);
   st.Push(2);
   st.Push(3);
   
   st.Pop();

   foreach (Object obj in st)
   {
    Console.WriteLine(obj);
   }
    Console.ReadKey();
  }
 }
}

Code تفسير:-

  1. هنا نقوم فقط بإصدار طريقة البوب ​​التي يتم استخدامها لإزالة عنصر من المكدس.

إذا تم إدخال الكود أعلاه بشكل صحيح وتم تشغيل البرنامج، سيتم عرض الإخراج التالي.

الإخراج:

المكدس في C#

يمكننا أن نرى أنه تمت إزالة العنصر 3 من المكدس.

دالة Stack Peek() في لغة C#

تعمل طريقتَا Push وPop مع أعلى المكدس، ولكن في بعض الأحيان تحتاج فقط إلى معاينة العنصر العلوي دون حذفه. تقوم طريقة Peek بذلك تحديدًا. فهي تُعيد القيمة العلوية للمكدس مع الحفاظ على المجموعة دون تغيير، وهو أمر مفيد عندما تريد اختبار العنصر التالي قبل حذفه.

الخطوة 1) أنشئ مكدسًا وادفع ثلاثة عناصر إليه، بحيث تكون القيمة 3 في الأعلى.

الخطوة 2) قم باستدعاء طريقة Peek لقراءة العنصر العلوي، ثم تحقق من خاصية Count للتأكد من عدم إزالة أي شيء.

using System;
using System.Collections;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Stack st = new Stack();
   st.Push(1);
   st.Push(2);
   st.Push(3);
   Console.WriteLine(st.Peek());
   Console.WriteLine(st.Count);
   Console.ReadKey();
  }
 }
}

Code تفسير:-

  1. تم تعريف مكدس باسم st، وتمت إضافة القيم 1 و2 و3 باستخدام طريقة Push، بحيث يصبح 3 هو العنصر العلوي.
  2. تقوم طريقة Peek بإرجاع العنصر العلوي دون إزالته، ولا تزال خاصية Count تعرض العدد الكامل للعناصر في المكدس.

عند تشغيل البرنامج، يقوم بطباعة القيمة 3 من بيك ثم العد 3وهذا يثبت بقاء العنصر في المكدس. أما إذا كان المكدس فارغًا، فإن دالة Peek تُصدر خطأً غير صالح.OperationException، لذلك من الآمن التحقق من Count قبل استدعائها.

مجموعة عامة شركة#

تستخدم الأمثلة أعلاه فئة Stack غير العامة من System.Collections، والتي تخزن كل عنصر ككائن. عادةً ما يفضل كود C# الحديث استخدام فئة Stack العامة. فئة من مساحة الاسم System.Collections.Generic. تربط هذه الفئة المكدس بنوع واحد مُعلن، لذا يتحقق المُصرّف من كل عملية دفع وسحب ولا حاجة إلى تحويل أو تغليف.

الفوائد الرئيسية للمجموعة العامة مدرجة أدناه.

  • أمان النوع: يتم تحديد النوع عند الإعلان عنه، لذلك لا يمكن دفع سوى القيم من هذا النوع، ويتم اكتشاف الأخطاء في وقت الترجمة.
  • ممنوع الملاكمة: يتم تخزين أنواع القيم مثل int بشكل مباشر، مما يتجنب تكلفة التغليف التي يدفعها Stack غير العام.
  • قراءات المنظف: تقوم الدالتان Pop و Peek بإرجاع النوع المعلن مباشرة، لذلك لا تقوم بتحويل النتيجة مرة أخرى من كائن.
using System;
using System.Collections.Generic;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Stack<string> st = new Stack<string>();
   st.Push("Java");
   st.Push("Python");
   Console.WriteLine(st.Pop());
   Console.ReadKey();
  }
 }
}

في هذا المثال، تم تعريف المكدس باسم Stack لذا فهي تقبل قيمًا نصية فقط. تُعيد دالة Pop سلسلة نصية مباشرةً وتطبعها. Python، آخر قيمة تم دفعها. بالنسبة لأي مشروع جديد، يكون المكدس العام وهو الخيار الموصى به.

الفرق بين المكدس والطابور في لغة C#

كومة و طابور كلاهما مجموعات تتحكم في ترتيب إزالة العناصر، لكنهما يستخدمان قواعد معاكسة. في المكدس، يكون الترتيب هو "آخر ما يُضاف، أول ما يُزال"، بينما في الطابور يكون الترتيب هو "أول ما يُضاف، أول ما يُزال". اختيار النوع المناسب يُوضح الغرض من الكود للمطورين الآخرين.

فيما يلي أبرز الاختلافات:

  • رقم الطلب تقوم المكدسة بإزالة العنصر المضاف حديثًا أولاً (LIFO)، بينما تقوم قائمة الانتظار بإزالة العنصر الأقدم أولاً (FIFO).
  • الأساليب: تستخدم المكدسة عمليتي الدفع والسحب، بينما تستخدم قائمة الانتظار عملية الإضافة إلى قائمة الانتظار والإزالة منها.
  • الوصول إلى العنصر العلوي: تقرأ المكدسة العنصر التالي باستخدام Peek، ويقرأ الطابور العنصر التالي باستخدام Peek من المقدمة.
  • الاستخدامات النموذجية: تتضمن المكدسات ميزات التراجع، وتقييم التعبيرات، والتكرار. tracالملك، بينما تتناسب قوائم الانتظار مع الجدولة والتخزين المؤقت والتنقل العرضي أولاً.

يتوفر كلا النوعين بشكل عام باسم Stack والطابور في System.Collections.Generic، لذلك تحصل على أمان النوع مع أي من الخيارين.

الأسئلة الشائعة

استدعاء دالة Pop أو Peek على مكدس فارغ يُنتج خطأً غير صالح.OperationException. تحقق من خاصية Count أولاً، أو استخدم طرق Stack العامة TryPop و TryPeek، والتي تُرجع خطأ بدلاً من طرح استثناء عندما لا يحتوي المكدس على أي عناصر.

تُنفذ عمليتا الإضافة والحذف في زمن ثابت O(1) لأنهما لا تتعاملان إلا مع الجزء العلوي من المكدس. وعندما يحتاج المصفوفة الداخلية إلى التوسع، تُجرى عملية إضافة عرضية لتغيير حجمها، لكن متوسط ​​تكلفة العملية الواحدة يبقى ثابتًا.

لا. لا يُظهر المكدس سوى العنصر العلوي من خلال دالتي Peek وPop، لذا لا يحتوي على مُفهرس مثل القائمة. لقراءة كل قيمة، استخدم حلقة foreach لتكرار عناصر المكدس أو انسخها باستخدام دالة ToArray.

تقوم الدالة Clear بإزالة جميع العناصر من المكدس دفعة واحدة، ثم تعيد ضبط قيمة Count إلى الصفر. لإزالة العناصر واحدًا تلو الآخر من الأعلى، استدعِ الدالة Pop في حلقة تكرارية حتى تصل قيمة Count إلى الصفر.

لا يُعدّ صنف Stack القياسي آمنًا للاستخدام المتزامن عند الكتابة إليه من قِبل عدة سلاسل عمليات في آنٍ واحد. وللوصول المتزامن، استخدم ConcurrentStack من System.Collections.Concurrent، الذي يوفر طريقتي TryPush وTryPop الذريتين دون الحاجة إلى أقفال خارجية.

استدعِ دالة ToArray لنسخ محتويات المكدس إلى مصفوفة جديدة، مرتبة من الأعلى إلى الأسفل. يمكنك أيضًا تمرير محتويات المكدس إلى مُنشئ List لإنشاء قائمة عامة مع الاحتفاظ بـping نفس الترتيب.

نعم. يقوم GitHub Copilot بكتابة تعريفات Stack، واستدعاءات Push وPop، وحلقات foreach من تعليق قصير أو اسم دالة. ويقترح غالبًا إصدار Stack العام، لأنه المجموعة الموصى بها لبرامج C# الجديدة.

نادرًا ما تخزن المكدسات بيانات تدريب ML.NET، التي تتدفق عبر مجموعات مُصنفة ومسار IDataView. ومع ذلك، يظهر مفهوم مكدس LIFO داخل خوارزميات التعلم الآلي للرجوعtracالملك، والبحث العميق أولاً، وإدارة استدعاءات الأساليب المتكررة.

تلخيص هذه التدوينة بـ: