• الإعلانات

    • فيصل الحربي

      تسجيل عضوية جديدة في المنتدى   01/31/2016

      السلام عليكم ورحمة الله وبركاته  عزيزي العضو الجديد :  حاليا رسالة الإيميل لتأكيد صحة إيميلكم تذهب للبريد العشوائي ( جاري حل المشكلة )  فإذا لم تجد رسالة التحقق من إيميلكم في صندوق الوارد لديكم إتجه للبريد العشوائي ( JUNK)  وقم بتفعيل إشتراككم من هناك   

البحث في المنتدى

Showing results for tags 'stack'.

  • البحث بالتاقات

    اكتب الكلمات المفتاحيه بينها علامه الفاصله
  • البحث بكاتب الموضوع

تم إيجاد 6 نتيجة

  1. ممكن تطبيقات المكدس العمليه في حياتنا لان مطلوب مني نسوي برنامج على تطبيق معين يعتمد مبدأ المكدس
  2. تعرف إلى std::stack

    السلام عليكم ورحمة الله وبركاته بنى المعطيات Data Structures هي طرق مجرّدة لحفظ البيانات أو الكائنات .. وأقصد بعبارة "طرق مجرّدة" أنها لا تحتاج إلى حاسوب مثلا لتكون موجوده .. كما أن الرياضيات هي أفكار مجرّدة والأرقام هي مفاهيم مجرّدة .. سنتحدث اليوم بإذن الله عن المكدّس Stack .. ولنبدأ بفكرته المجرّدة .. بعد وجبة دسمة ستذهب حضرتك لترتاح أو لتتابع العمل على مشروعك .. :) ولكن هناك من سيتحمّل عبء تنظيف الصحون ! في مرحلة معينة من تنظيف الصحون سيحدث ما يلي : نقوم لتنظيف الصحن ثم نضعه جانباً .. بشكل أفقي /_____\ ثم نقوم بتنظيف صحن آخر ونعضع فوق الصحن الأول /====\ وهكذا سنضع صحنا فوق آخر .. في شكل رياضي مجرّد اسمه( المكدّس ) حيث تتكدّس العناصر فوق بعضها .. والآن : نريد اعادة ترتيب الصحون .. ونظريّا يستحيل أن نسحب الصحن في الأسفل فهذا سيؤدي إلى انهيار المكدس .. ولذلك نقوم بسحب الصحن على السطح أولاً .. ثم الذي يليه ثم الذي يليه .. حتى نصل إلى الصحن في الأسفل .. ما الذي حدث الآن ؟ أول صحن وضعناه (نسمي عملية الوضع  بـالدفع push ) هو آخر صحن سحبناه (نسمي عملية السحب بالإخراج pop ) وهذا ما نسمّيه (أول عنصر يدخل هو آخر عنصر يخرج .. وبالتالي : آخر عنصر يدخل هو أول عنصر يخرج ) إذا نطلق على المكدّس لقب LIFO أي Last in First Out وهذا هو التعريف الرياضي له .. إذاً : المكدّس هو حاوية آخر ما يدخل إليها هو أول ما يخرج .. أما الحاوية التي صفتها : أول من يدخل هو أول من يخرج فتسمّى : الطابور Queue ولن نتطرق اليها اليوم . لنتكلّم الآن عن بعض العمليات التي يمكننا القيام بها في المكدس ( لانزال نعالج الفكرة المجرّدة ..بدون أي برمجة أو تطبيق عملي ) 1- يمكننا الدفع بعنصر داخل المكدس Push 2- يمكننا إخراج عنصر من المكدس Pop 3- العنصر الوحيد الذي يمكننا رؤيته هو الذي على السطح .. وبالتالي يمكننا معرفة العنصر على السطح .. ولنسمّ العملية هذه top 4- يمكننا معرفة ما إذا كان المكدّس خالياً تماماً ... empty 5- بقي أخيراً أنه بالإمكان أن نعد عدد العناصر في المكدس .. size ( مثلاً ان تعد الصحون المتكدسة فوق بعضها ) هذا ينطبق على أي مكدّس مهما اختلفت الروايات :) والآن لنبدأ بالتطبيق العملي .. إنه لمن الممتع أن تكتب الكود بنفسك فستطبق بذلك ما تعلمته عن المكدس برمجياً وهذا أمر في غاية المتعة .. وأنصحك بالقيام بهذه الخطوة لوحدك :) ولكننا سنتعرف هنا على النوع stack والموجود ضمن المكتبة stack ضمن نطاق الأسماء std في ++C وسنتعامل مع توابعه الجاهزة والمحكمة البناء :) بعد تضمين المكتبة stack #include<stack>واستخدام stack من مساحة الأسماء std using std::stack;نقوم بتعريف stack في البرنامج كما يلي : stack <int>M;//stack <any type or class>M;لاحظ أن المكدس هو قالب template مما يسمح لنا بإنشاء مكدسات لأي نوع أو صف ... (نكتب اسم النوع بين <> ) لنتعرف على التوابع الموجودة في الكائن من نوع stack أولا الدفع push وهو يأخذ وسيطا من النوع الذي قمنا باستخدامه في القالب (وهو في المثال int) ويعيد void for(int i=0;i<10;i++)M.push(i);ثانيا الاستخراج pop وهو يزيل العنصر الذي على السطح .. ويعيد void "انتبه" pop لايعيد العنصر المزال .. M.pop();M.pop();ملاحظة هامة : لو قمنا بعمل pop للكدس وهو فارغ أصلا سيتوقف البرنامج عن العمل . ولذلك علينا معرفة :  هل المكدس فارغ أم لا ؟ عندما نستخدم pop وذلك باستخدام empty الذي يعيد 0 أو 1 حسب الحالة كما يلي : if(!M.empty())    M.pop();ثالثا  معرفة العنصر الذي على السطح باستخدام top والذي يعيد مرجعا ثابتا لأول عنصر ( أي انه لا يمكن تعديل العنصر ) std::cout<<M.top()<<std::endl;أخيراً يمكننا معرفة حجم المكدّس بالتابع size std::cout<<M.size()<<std::endl;من أشهر الحلقات المستخدمة مع المكدّس هي الحلقة من الشكل التالي : for(;!M.empty();M.pop())function(M.top);أي أننا نستخرج عناصر المكدس واحدا واحدا حتى يفرغ .. ونطبق التابع function أياً يكن ... على كل عنصر نمر عليه فيما يلي مثال يوضح العمليات السابقة .. سندخل نصوصاً في المكدس ثم سنستخرجها ونطبعها .. #include <iostream>#include <stack>#include <string>using std::string;using std::stack;using std::cin;using std::cout;using std::endl;int main(int argc,char**argv){    stack<string> x;    string y;    cout<<"Enter String !"<<endl;    cin>>y;    while(y.compare("end"))    {        x.push(y);        cin>>y;    }    cout<<"size="<<x.size()<<endl;    for(;!x.empty();x.pop())        cout<<x.top()<<endl;    return EXIT_SUCCESS;}البرنامج السابق يحفظ النصوص في مكدّس حتى ندخل end ثم يقوم بطباعتها بعكس الترتيب المدخل (لأن المكدس هو LIFO ) يمكنك الآن استعمال المكدس المعرف في المكتبة stack  دون ان تضطر لاعاداة كتابة كل شيء بنفسك (لتسريع الانجاز وتخفيض الاخطاء ) بالتوفيق :)   كيف يمكنك اغناء المشاركة ... 1- يمكنك كتابة برنامج يوضح استخدام المكدّس مع الكائنات المنشأة من صف ما .. أنشئ صفا بسيطا وكائنات منه ثم ضعها في مكدس .. 2- يمكنك كتابة مثال آخر على استخدام الدالة باستخدام الأنواع البسيطة . 3- يمكنك تقديم روابط تشرح stack من مصادر أخرى .. بشكل أفضل  .. وهنا أرغب بذكر المرجع الرائع مقالات الأخ Snack3r وهذا مقاله عن المكدسات 4- يمكنك كتابة موضوع عن استخدام هياكل بيانات أخرى مثل Tree  مثلاً كيف يمكنك الاساءة الى المشاركة .. 1-أن ترد بكلمة شكر فقط .. 2- أن تسأل عن أمر غير متعلق بالموضوع ..   والسلام عليكم ورحمة الله وبركاته
  3. بسم الله الرحمن الرحيم في هذه المقالة سأتعرض لموضوع مهم جداً يهم المطورين المبتدئين بشكل خاص حيث عليهم أن يدركوه جيداً .. خصوصاً أن بعض أسئلة الانترفيو تكون حوله .. إنه الفرق بين Reference Types و Value Types.... في عالم الدوت نت انواع البيانات هي ثلاث أنواع : Reference Types - Value Types - Pointer Types .. معظم إستخدامنا مع البيانات هو مع النوعين الاولين اما Pointer Types فهو يستخدم نادراً.   ما الفرق بينهما؟ لديك صديق طلب منك عدد الأمس من جريدة ما .. لديك خياران: الأول أن تبعث له على الإيميل عنوان URL لموقع الجريدة على الإنترنت، و الثاني أن تذهب لتقابله في مكان ما و تعطيه نسخة من الصحيفة الورقية من الجريدة .. بالتأكيد الحل الأول أسرع و أفضل و لكن في بعض الحالات قد ألجأ للحل الثاني .. لذا علينا أن نعرف عندما نريد أن ننشأ أنواع البيانات بأنفسنا هل نجعلها Reference أم Value .   عندما تستخدم Value Type فإن CLR يقوم بحجز مكان في جزء Stack من الذاكرة و هذا المكان يحتوي على نسخة من النوع لها قيمة (نسخة ورقية من الجريدة)، أما عندما تستخدم Reference Type فإنCLR سيحجز مكان في Heap لقيمة النوع و عنوان (أو مؤشر أو مرجع) في الجزء Stack(عنوان URL لموقع الجريدة). أنظر لهذا الكود: int x = 5;ReferenceType r_type = new ReferenceType();سيتم تخزين قيمة X في Stack .. أما قيمة الكائن r_type فستخزن في Heap و سيخزن عنوان لهذه القيمة في Stack.     و هنا قد يظهر سؤال: لماذا هذا التعقيد .. لماذا لا تكن البيانات كلها من نوع واحد؟ الإجابة أن إستخدامات كلاهما تختلف .. فالأنواع Value Types تسند لها قيمة محددة واحدة مثل: int i=4;boolean log=true;أما النوع Reference Types فهو قد يحتوي على مجموعة بيانات مركبة و معقدة و من الصعب وضعها جميعاً في مكان واحد في Stack، لذا فهي تخزن في Heap و يخزن العنوان او المرجع لهذه البيانات في Stack، و الإعتماد على هذه التقنية أسرع في المعالجة لذا عندما تريد إنشاء فئة ستقوم مثلاً بإجراء عمليات معينة على قاعة بيانات أو فئة تقوم بعمل مصفوفة تستقبل بيانات من أنواع مختلفة فلابد من جعل فئتك Reference Type، أما إذا كنت تريد إنشاء فئة تعرض فقط مجموعة إختيارات  (ذكر/ أنثى) مثلا فهنا تستخدم فئة Value Type.   من الفروق الأخرى بينهما أن إنشاء فئة من نوع Reference Type يكون عن طريق كلمة class و النوع Value Type عن طريق كلمة struct: public class ReferenceType{ public int Field { get; set; } } public struct ValueType{ public int Field { get; set; }}فرق آخر بينهما، النوع Reference Type يرث من System.Object اما Value Type فهو يرث من System.ValueType التي ترث بدورها System.Object.   لمزيد من الفهم عن النوعين ننظر لهذا المثال: class Program { static void Main(string[] args) { Console.WriteLine("Reference Type:"); ReferenceType r_type1 = new ReferenceType(); ReferenceType r_type2 = new ReferenceType(); Console.WriteLine(r_type1.Equals(r_type2)); Console.WriteLine("Value Type:"); ValueType val1 = new ValueType(); ValueType val2 = new ValueType(); Console.WriteLine(val1.Equals(val2)); Console.ReadLine(); } } public class ReferenceType { } public struct ValueType { }Equals method هي وسيلة للتأكد ما إذا كان كائنين مساويين لبعض و هي ترجع true إذا كان الكائنين متساويين أو false إذا كانا غير ذلك .. قد يتبادر إلى ذهنك ان ناتج جملة Console.WriteLine الأولى سيكون true و الثانية ايضاً true، و لكن الحقيقة أن الأولى ستكون false لماذا ؟؟ لأن كلاً من r_type1 و r_type2 لهما reference مختلف في Stack، فكلاهما يشير لموضع قيم مختلفة في Heap. أما جملة Console.WriteLine الثانية فناتجها هو true لأن الوسيلة Equals هنا تقارن بين القيمتين بشكل مباشر و قيمة val1 و val2 متساويتين.   فللنظر لهذا المثال أيضاً: class Program { static void Main(string[] args) { Console.WriteLine("Reference Type:"); ReferenceType r_type1 = new ReferenceType(); ReferenceType r_type2 = r_type1; Console.WriteLine(r_type1.Equals(r_type2)); Console.WriteLine("Value Type:"); ValueType val1 = new ValueType(); ValueType val2 = val1 ; Console.WriteLine(val1.Equals(val2)); Console.ReadLine(); } }هنا سنجد ناتج الجملتين true .. لأن ReferenceType r_type2 = r_type1 معناها أن مرجع r_type2 هو نفسه مرجع r_type1، أي أن CLR قام بنسخ مرجع r_type1 و أعطاه لr_type2، إذن كلاهما يشير لنفس القيمة في Heap.   لتوضيح الفكرة السابقة نستعرض هذا المثال: class Program { static void Main(string[] args) { ReferenceType r_type1 = new ReferenceType();            ReferenceType r_type2 = r_type1;            Console.WriteLine("Before:");            Console.WriteLine(r_type1.r_field);            r_type2.r_field = 5;            Console.WriteLine("After:");            Console.WriteLine(r_type1.r_field);            Console.ReadLine(); } } public class ReferenceType { public int r_field { get; set; } }عند تنفيذ الكود سنجد ان ناتج سطر Console.Writeline الأول هو 0 و الثاني هو 5 .. لماذا؟ لأننا أخبرنا البرنامج ان مرجع r_type1 هو نفسه مرجع r_type2 و لم نكن قد أعطينا بعد أي قيمة للخاصية r_field في الكائن r_type2 .. لذا فقيمة الخاصية r_field في الكائن r_type1 هي القيمة القياسية 0، ثم أعطينا القيمة 5 لr_field  في الكائن r_type2، و لأن مرجعي الكائنين هما متساويين فهما يشيران لنفس القيمة، لذا سنجد ان مرجع r_type1 يشير للقيمة 5 أيضاً و بالتالي ستكون قيمة الخاصية r_field في r_type1 هي 5 أيضاً برغم أننا لم نعطها أي قيمة.     لنرى هل يمكن تطبيق نفس الفكرة على الأنواع ValueType: class Program { static void Main(string[] args) { Console.WriteLine("Before:"); ValueType val1 = new ValueType(); ValueType val2 = val1; Console.WriteLine(val1.v_field ); Console.WriteLine("After:"); val2.v_field = 5; Console.WriteLine(val1.v_field); Console.ReadLine(); } } public struct ValueType { public int v_field { get; set; } }هنا سنجد ان ناتج تنفيذ البرنامج هو 0 في المرتين، لأنك عندما تنشئ كائنات من النوع ValueType فإنك تنشئ نسخ من الفئة الأصلية و كل نسخة مستقلة عن الأخرى فمهما تغيرت قيمة الخاصية v_field في الكائن val2 فلن تتغير نظيرتها في الكائن val1     من الفروق الأخرى أن النوع ValueType لا يمكن الوراثة منه، اما Reference Type فيمكن ذلك.
  4. السلام عليكم ورحمة الله وبركاته اريد معرفة طريقة كتابة دوال push و pop الخاصة بالstack في C++ ؟ بداخل الclass
  5. أتمنى ما يكون متكرر وهو : نريد كتابة دالة تنسخ stack of integers إلى stack أخرى بحيث لا يمكن تعريف أي متغير في الدالة غير هذه المتغيرات وهي : 3 أعداد صحيحة (فقط) مثال stack1: 1 6 8 4 5stack2: emptyafter the function that take the two stacks as a parameter  (you can use in the function only three integers) stack1: 1 6 8 4 5stack2: 1 6 8 4 5ملاحظة : رأس الدالة pop بالشكل التالي: int pop()
  6. السلام عليكم و رحمة الله و بركاته سؤالي الذي اقوم بحله طرح في موضوع اخر احببت هنا ان اشرح قليلا و لدي بعض الاسئلة البرنامج عبارة عن class DQ , inherits from the class queue كذا جا بالسؤال بعدين كتبوا the class DQ is a generalization of both stack and queue??? بس الفنكشنز المطلوبة ما تدل على اننا نحتاج استخدام الستاك و الكيو مع بعض كلها ممكن تعمل بكيو ماعدا واحدة • P- Push the next input character to the front. طيب يعني اخلي الdq مكون من الستاك مثلا يعني composite بما انه ما ذكر ان فيه inheritens او مالعمل؟ سوالي الاخر • X- Extract the rear of the q • W- Retrieve and write the rear entry. .ايش الفرق بينهم.؟ ال retreive معروف انها بس تسترجع العنصر , طيب ال extract وش تسوي؟؟