• الإعلانات

    • فيصل الحربي

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

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

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

Showing results for tags 'search'.

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

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

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

  1. اجهزة الكشف عن المعادن شركة كينج الهندسية المتخصصة في جميع الأنظمة الأمنية تقدم لعملائننا الكرام حلول امنية متكاملة من موديلات عالمية  للكشف عن المعادن  تستخدم للسيارات والافراد وللحقائب ومنها بوابات كشف المعادن والكواشف اليدوية عن للمعادن ومرآة التفتيش أسفل السيارات. حيث تقدم الشركة خدماتها في مجال أنظمة الأمن والمراقبة بتوفير أحدث تكنولوجيا في مجال الكشف عن المتفجرات (بوابة أمنية  - كاشف يدوي - مرآه تفتيش اسفل السيارات).  فالشركة تقدم ضمان على جميع الأجهزة لمدة سنة ضد عيوب الصناعة من تاريخ التركيب.  وأيضاً خدمات التركيب والبرمجة والصيانة والتدريب على استخدام جميع الأجهزة                                               الماركات المتاحة JEWON الكورية /  AutoClear الأمريكية /  GARRETT  الأمريكية / الكورية MICRO /  التركي SECUDA /  الكوريه  SUPER SCANNER /  HST [url=https://www.0zz0.com][/url] [url=https://www.0zz0.com][/url] [url=https://www.0zz0.com][/url] للاستفسار موبايل:   01007771327  - 01007773521 01000127629 - 01143100053 – 01020002971 العنوان :10 الشطر العاشر بجوار كارفور المعادي القاهرة Email: [email protected] Website: http://www.ksedco.com YouTube: https://www.youtube.com/channel/UC4uDtUd2oRuSum3ChmMBeTw   Facebook: https://www.facebook.com/ksedco.company/ Google+: https://plus.google.com/100471050354784765950/posts BlogSpot: http://ksedco.blogspot.com/ الكلمات الدلالية بوابات امنية ,  كاشف يدوي , كواشف يدوية في مصر, القاهرة , الاسكندرية , السويس , مرآه التفتيش تحت السيارات ’ بوابة أمنية , بوابه الكشف عن المعادن , الذهب , الحديد , الرصاص, المعدن , مراه مقعرة , مرأة محدبة , بوابات داخلية , خارجية , انظمة امن للبيع , كينج الهندسية Metal detector , Hand Held , Under Vehicle Search Mirror , Ksedco , King Sedco , for sale , in Egypt cairo , alex القاهرة - الجيزة - القليوبية الإسكندرية - البحيرة - مطروح الدقهلية - كفر الشيخ - الغربية - المنوفية - دمياط بورسعيد - الإسماعيلية - السويس - الشرقية - شمال سيناء - جنوب سيناء بني سويف - المنيا - الفيوم أسيوط - الوادي الجديد سوهاج - قنا - الأقصر - أسوان - البحر الأحمر Cairo - Giza - Qalyubia Alexandria - Bahrin - Matrouh Dakahlia - Kafr el-Sheikh - Gharbiya - Monoufia - Damietta Port Said - Ismailia - Suez - Alsharkia‏ - North Sinai - South Sinai Beni Suef - Minia - Fayoum Assiut - Wady gaded Sohag - Qena - Luxor - Aswan – Sharm El-Sheikh, Hurgada, Ain El-Sokhna - Red Sea  
  2. السلام عليكم يوجد عندى شكل من أشكال البحث وهو ان اريد ان اعمل بحث على القيم المضافة فقط داخل هذا الشكل بحيث عندما اكتب رقم قومى فقط يغطى لى نتائج بالرقم القومى وعند اضافة قيمة اخرى مثل الاسم يعطى لى نتائج على اسم والرقم القومى فقط .. وعند اضافة او تحديد المحاقظة يعطى لى نتائج على الاسم والرقم والمحافظة ... هكذا كلما اضافت قيمة للبحث عنه يغطى لى نتائج .... بأستخدام linq + c sharp + asp .net وشكرا يوجد الشكل فى المرفقات   
  3. اجهزة الكشف عن المعادن شركة كينج الهندسية المتخصصة في جميع الأنظمة الأمنية تقدم لعملائننا الكرام حلول امنية متكاملة من موديلات عالمية  للكشف عن المعادن  تستخدم للسيارات والافراد وللحقائب ومنها بوابات كشف المعادن والكواشف اليدوية عن للمعادن ومرآة التفتيش أسفل السيارات. حيث تقدم الشركة خدماتها في مجال أنظمة الأمن والمراقبة بتوفير أحدث تكنولوجيا في مجال الكشف عن المتفجرات (بوابة أمنية  - كاشف يدوي - مرآه تفتيش اسفل السيارات).  فالشركة تقدم ضمان على جميع الأجهزة لمدة سنة ضد عيوب الصناعة من تاريخ التركيب.  وأيضاً خدمات التركيب والبرمجة والصيانة والتدريب على استخدام جميع الأجهزة                                               الماركات المتاحة JEWON الكورية /  AutoClear الأمريكية /  GARRETT  الأمريكية / الكورية MICRO /  التركي SECUDA /  الكوريه  SUPER SCANNER /  HST [url=https://www.0zz0.com][/url] [url=https://www.0zz0.com][/url] [url=https://www.0zz0.com][/url] للاستفسار موبايل:   01007771327  - 01007773521 01000127629 - 01143100053 – 01020002971 العنوان :10 الشطر العاشر بجوار كارفور المعادي القاهرة Email: [email protected] Website: http://www.ksedco.com YouTube: https://www.youtube.com/channel/UC4uDtUd2oRuSum3ChmMBeTw   Facebook: https://www.facebook.com/ksedco.company/ Google+: https://plus.google.com/100471050354784765950/posts BlogSpot: http://ksedco.blogspot.com/ الكلمات الدلالية بوابات امنية ,  كاشف يدوي , كواشف يدوية في مصر, القاهرة , الاسكندرية , السويس , مرآه التفتيش تحت السيارات ’ بوابة أمنية , بوابه الكشف عن المعادن , الذهب , الحديد , الرصاص, المعدن , مراه مقعرة , مرأة محدبة , بوابات داخلية , خارجية , انظمة امن للبيع , كينج الهندسية Metal detector , Hand Held , Under Vehicle Search Mirror , Ksedco , King Sedco , for sale , in Egypt cairo , alex القاهرة - الجيزة - القليوبية الإسكندرية - البحيرة - مطروح الدقهلية - كفر الشيخ - الغربية - المنوفية - دمياط بورسعيد - الإسماعيلية - السويس - الشرقية - شمال سيناء - جنوب سيناء بني سويف - المنيا - الفيوم أسيوط - الوادي الجديد سوهاج - قنا - الأقصر - أسوان - البحر الأحمر Cairo - Giza - Qalyubia Alexandria - Bahrin - Matrouh Dakahlia - Kafr el-Sheikh - Gharbiya - Monoufia - Damietta Port Said - Ismailia - Suez - Alsharkia‏ - North Sinai - South Sinai Beni Suef - Minia - Fayoum Assiut - Wady gaded Sohag - Qena - Luxor - Aswan – Sharm El-Sheikh, Hurgada, Ain El-Sokhna - Red Sea  
  4. السلام عليكم ورحمة الله وبركاته   لتكن لدينا القائمة التالية : 1 2 7 9 5 3 4 نقول أن 2 هي الحد العلوي للـ 1 , والـ7 هو الحد العلوي للـ 5 , ببساطة لو قمنا بترتيب القائمة فإن الحد العلوي لقيمة ما هو القيمة التي تليها في القائمة ( من أجل قائمة لا تحوي عناصر متكررة )   يعيد لنا التابع std::upper_bound الموجود في المكتبة  algorithm مؤشراً أو iterator للحد العلوي لقيمة ما داخل قائمة مرتّبة, (أي : مؤشراً لأصغر قيمة ممكنة أكبر تماماً من قيمة الوسيط )   لو : بفرض أننا نبحث عن الحد العلوي للقيمة x : لو كانت القيمة x أكبر من أكبر قيمة في القائمة فإن التابع سيعيد مؤشراً إلى ما بعد نهاية القائمة وعندها لا يجوز محاولة الوصول إلى محتوى ما يشير إليه المؤشر لأن ذلك سينتج undefined behavior لو كانت القيمة x  أصغر من أصغر قيمة في القائمة فسيعيد التابع مؤشراً إلى أصغر عنصر في القائمة (حالة طبيعية ) لو كانت القيمة x غير موجودة في القائمة إلا أنها ليست إحدى الحالتين السابقتين فإن التابع يعيد مؤشراً إلى أصغر قيمة موجودة أكبر من x لو كانت القيمة x موجودة فإن التابع يعيد مؤشراً إلى القيمة التي بعدها , مما يعني أنه في حال كانت القيمة x موجودة في نهاية القائمة فسيعيد التابع مؤشراً إلى ما بعد نهاية القائمة   لتلخيص جميع الحالات السابقة في عبارة واحدة نقول أن التابع upper_bound يعيد مؤشراً أو iterator إلى أول عنصر في المجال المعطى يحقق كونه أكبر من القيمة المراد البحث عنها , وإن لم يجد يعيد مؤشراً إلى ما بعد نهاية المجال .   أما أخوه الشقيق التابع std::lower_bound فعلى عكس ما يوحي به الاسم ! إنه لا يعيد مؤشراً لأكبر قيمة أصغر من قيمة معينة . يعيد التابع lower_bound مؤشراً أو iterator لأول عنصر في المجال المعطى ليس أصغر من القيمة المراد البحث عنها ,وإن لم يجد يعيد مؤشراً إلى ما بعد نهاية المجال .   تحذيرات : يجب أن تكون القائمة مرتبة وفقاً لنفس نوع المقارنة الذي سيستخدمه التابع للعثور على الحد العلوي أو السفلي .التابع upper_bound يعيد مؤشراً لعنصر أكبر تماماً من القيمة المحددة بينما يعيد lower_bound يعيد مؤشراً لعنصر أكبر أو يساوي القيمة المحددة (إن وجدت )لنبدأ بالتابع std::upper_bound : تعريف التابع : كما اعتدنا في توابع STL التي تقوم بالمقارنة فإن للتابع upper_bound تعريفان على شكل قوالب , الأول يستخدم عملية المقارنة > لمقارنة العناصر والعثور على الحد العلوي , والثاني يستخدم تابع يمرر كوسيط للمقارنة : الشكل الأول (الافتراضي) : template <class ForwardIterator, class T> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val);يعيد التابع  ForwardIterator يشير إلى الحد العلوي ويأخذ ثلاثة وسطاء : الوسيط الأول هو  ForwardIterator يشير للعنصر الأول في القائمة المراد البحث بداخلها . الوسيط الثاني هو  ForwardIterator يشير للعنصر الذي يلي العنصر الأخير في القائمة المراد البحث بداخلها . الوسيط الثالث هو العنصر المراد على العثور على الحد العلوي له . أي أن أول وسيطين يحددان المجال المراد البحث فيه من first إلى ما قبل last . الشكل الثاني للتابع (المخصص ) : template <class ForwardIterator, class T, class Compare> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp);يضاف له وسيط رابع هو تابع مقارنة (يمكن أن يكون تابعاً عادياً يعيد قيمة bool أو functor كما في greater<int>()l أو تعبير lambda .. يمكنك مراجعة الموضوع التالي للمزيد عن طرق تعريف الوسيط compare )   إن جسم التابع مكافئ للجسم التالي : template <class ForwardIterator, class T> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val){ ForwardIterator it; iterator_traits<ForwardIterator>::difference_type count, step; count = std::distance(first,last); while (count>0) { it = first; step=count/2; std::advance (it,step); if (!(val<*it)) // or: if (!comp(val,*it)), for version (2) { first=++it; count-=step+1; } else count=step; } return first;}لاحظ وجود عملية بحث ثنائي داخل القائمة .   هذا مثال على استخدام التابعين من المرجع: // lower_bound/upper_bound example#include <iostream>     // std::cout#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort#include <vector>       // std::vectorint main () {  int myints[] = {10,20,30,30,20,10,10,20};  std::vector<int> v(myints,myints+8);           // 10 20 30 30 20 10 10 20  std::sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30  std::vector<int>::iterator low,up;  low=std::lower_bound (v.begin(), v.end(), 20); //          ^  up= std::upper_bound (v.begin(), v.end(), 20); //                   ^  std::cout << "lower_bound of 20 " << *low << '\n';  std::cout << "upper_bound of 20 " << *up  << '\n';  return 0;}إذا كانت القائمة لا تسمح بالوصول العشوائي non-random-access فإن التابع سيستغرق زمناً (O(N للوصول إلى الحد العلوي أو السفلي , أما إن كانت تدعم الوصول العشوائي فسيتم إجراء مقارنة log2(N)+1 مقارنة .   لننتقل إلى التابع lower_bound : تعريف التابع : مثل سابقه بشكلين , والوسطاء لها نفس الدلالات الشكل الافتراضي : template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val);الشكل المخصص : template <class ForwardIterator, class T, class Compare> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp);كما ذكرنا سابقاً فهو يعيد مؤشراً لأول عنصر في المجال من first إلى ما قبل last يحقق كونه ليس أصغر من val (لو كانت val أكبر من جميع العناصر سيعيد last )   يمكن أن يكون شكل جسم التابع مكافئ لما يلي : template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val){ ForwardIterator it; iterator_traits<ForwardIterator>::difference_type count, step; count = distance(first,last); while (count>0) { it = first; step=count/2; advance (it,step); if (*it<val) { // or: if (comp(*it,val)), for version (2) first=++it; count-=step+1; } else count=step; } return first;}تحذير : لا يجوز استخدام عملية الـ* للوصول إلى محتوى المؤشر أو الـ iterator إلا إذا كان لا يساوي last (أي يجب التأكد من صلاحية المؤشر أولاً ) والآن لننتقل إلى الجزء الماتع , توظيف التابعين :   1- استخدام lower_bound للبحث الثائي , بل وأفضل : عندما نحتاج البحث عن عنصر ما , فإن البحث الثنائي من أسرع خوارزميات البحث بزمن (log2(N ولكن للأسف , يعيد التابع std::binary_search يعيد فقط true أو false للدلالة على وجود أو عدم وجود القيمة المراد البحث عنها , فكيف يمكننا الوصول للقيمة ؟ أو رقمها في الفهرس ؟ أو القيمة التي قبلها ؟ كل هذا من وظيفة التابع lower_bound تذكرة : يعيد lower_bound مؤشراً لأول عنصر أكبر أو يساوي العنصر الذي نبحث عنه (إن وجد) مثال : // lower_bound/upper_bound example#include <iostream>     // std::cout#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort#include <vector>       // std::vectorint main (){    int myints[] = {4,2,3,5,7,8,9,1};    std::vector<int> v(myints,myints+8);    std::sort (v.begin(), v.end());    for(auto x:v)        std::cout<<x<<" ";    std::cout<<std::endl;    for(int y=0; y<10; y++)    {        int index=lower_bound (v.begin(), v.end(), y) - v.begin();        if(v[index]==y)            std::cout<<y<<" is exist with index : "<<index<<std::endl;        else            std::cout<<"we can't find "<<y<<" but the first bigger is "<<v[index]<<std::endl;    }    return 0;}للتأكيد على أن التابع يستخدم البحث الثنائي , لنقم بما يلي : 1- تعريف تابع مقارنة خاص , يحوي بداخله تابع لطباعة العددين الذين يتم مقارنتهما 2- استدعاء الشكل المخصص للتابع وتمرير تابع المقارنة له . 3- تمرير مصفوفة من 32 عنصرأ والبحث عن العنصر الأخير (الحالة الأسوأ) ويجب ان ينفذ التابع فقط 5 مقارنات .   راقب وافهم عمل الكود التالي : // lower_bound/upper_bound example#include <iostream>     // std::cout#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort#include <vector>       // std::vectorbool comp(const int&a,const int&b){    std::cout<<a<<" "<<b<<std::endl;    return a<b;}int main (){    std::vector<int> v(32);    for(int i=0;i<32;i++)        v[i]=i;    lower_bound (v.begin(), v.end(),31,comp);    return 0;} بالمناسبة :إذا كان العنصر المراد البحث عنه متكرراً عدة مرات في القائمة فإن خوارزمية البحث الثنائي المعتادة لا تفرّق بين العثور على أول وجود له أو آخر وجود له , المهم أن تعثر عليه كيفما كان ولكن lower_bound تضمن لك العثور على أول ظهور له مما يزيد من فائدتها .   2- استخدام الفرق بين نتيجتي  lower_bound وupper_bound  لمعرفة عدد مرات تكرار العنصر :   إن lower_bound تعيد مؤشر لأول ظهور لعنصر ما (إن وجد ) أما upper_bound فتعيد مؤشر لما بعد آخر ظهور لعنصر ما (إن وجد) أما إن كان غير موجود فسيعيدان نفس  المؤشر لأول عنصر أكبر من العنصر المراد . إذا عند طرح قيمة المؤشر الخاص بـ upper_bound من مؤشر lower_bound سيعطينا شيئاً ما :) انظر للقائمة التالية : 6 5 5 5 4 2 1 ببدء الترقيم من الصفر , فإن lower_bound ستعيد 3 و upper_bound ستعيد 6 ( للتسهيل سنعتبر أنها تعيد الـ index إلا أنها تعيد مؤشر وعلينا طرحه من first للحصول على الـ index ) لاحظ أن ناتج upper_bound - ناتج lower_bound = عدد مرات التكرار = 3 // lower_bound/upper_bound example#include <iostream>     // std::cout#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort#include <vector>       // std::vector#include <cstdlib>      // rand,srand#include <ctime>        // timeint main (){    std::vector<int> v;    srand(time(0));    for(int i=0;i<10;i++)        {            int repeat=rand()%10;            for(int j=0;j<repeat;j++)                v.push_back(i);        }        int s=5;//search for 5    std::cout<< upper_bound (v.begin(), v.end(),s) - lower_bound (v.begin(), v.end(),s) << std::endl;    for(auto x:v)        std::cout<<x<<" ";    return 0;}3-هل العنصر موجود ؟   هذه الفقرة فقط لتأكيد فهمك للموضوع , وعليك الإجابة الآن : هل التابع التالي يصلح للاستخدام كـ binary_search في vector ؟ bool binary_search_2(std::vector<int>x,int y){    sort(x.begin(),x.end());    if( upper_bound(x.begin(),x.end(),y) == lower_bound(x.begin(),x.end(),y) )        return false;    return true;}جرب الكود التالي : // lower_bound/upper_bound example#include <iostream>     // std::cout#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort#include <vector>       // std::vector#include <cstdlib>      // rand,srand#include <ctime>        // timebool binary_search_2(std::vector<int>&x,int y){    sort(x.begin(),x.end());    if( upper_bound(x.begin(),x.end(),y) == lower_bound(x.begin(),x.end(),y) )        return false;    return true;}int main (){    std::vector<int> v;    srand(time(0));    for(int i=0;i<100;i++)        v.push_back(rand()%100);    if(binary_search_2(v,23))        std::cout << "By Mostafa 0x36a2"<<std::endl;    else        std::cout << "ArabTeam2000"<<std::endl;    for(int i=0;i<100;i++){        if(i and i%10==0)            std::cout<<std::endl;        std::cout<<v[i]<<" ";    }    return 0;}أخيراً تجدر الإشارة إلى أن التابع lower_bound مفيد جداً في تنفيذ خوارزمية longest increasing sub-sequence حيث يجعل زمن التنفيذ (O(n2المعتاد للخوارزمية أفضل بكثير (O(n log2n   وتجدر الإشارة أيضاً إلى وجود نسخ من التابع تختص بالتعامل مع std::set التي تمثل كشجرة بحث ثنائية تسمح بتنفيذ lower_bound بشكل فعال .   المرجع : cplusplus : lower_bound upper_bound مصادر : stackoverflow فهم القيمة المعادة من التابعين ماذا يحدث عند عدم وجود العنصر lower_bound == upper_bound     خاتمة : أخي الكريم , المقال الذي بين يديك تحت رخصة (اكتب بالقدر الذي تستطيعه , سيتابع أحدهم من بعدك !) لذلك واجبك بعد قراءة المقال الزيادة عليه أو على سواه , بالسؤال عن ما لم تفهمه , او بتطبيق مفيد أو رابط متعلق به , أو بالتنبيه للأخطاء فيه أو تحسينها , كما يحق لك نشره إن وجدت فيه الفائدة , يمكنك جمعه مع مقالات أخرى لنشر كتاب مجاني . ساهم برفع المستوى العلمي العربي , وتجنب الردود الخالية من الفائدة لمن سيأتي من بعدك .     والله ولي التوفيق
  5. السلام عليكم ورحمة الله وبركاته كثيراً ما نحتاج البحث عن أكبر عنصر أو أصغر عنصر في قائمة/مصفوفة/سلسلة/أو أي شيء يمكننا التأشير إليه (أي كل ما يملك ForwardIterator ) فالبحث عن اكبر عنصر هو عملية أساسية في Selection sort كما في Pancacke sort عدا عن كونه عملية أساسية مستقلة للكثير من الحسابات الهامة كإيجاد أفضل الطلاب في قائمة أو العثور على أقصر الطرق ضمن قائمة طرق متاحة مثلاً .. ورغم أنها عملية سهلة التكويد (كتابة الكود) بشكل كبير , إلا ان وجود حلقة البحث داخل الكود غالباً يسبب المزيد من الصعوبة في فهم الكود , كما أنه لا داع لتوضيح أهمية استخدام الأدوات الجاهزة في تسريع عملية التطوير  . لنبدأ إذا في التعرف على استخدام التابع max_element من مكتبة algorithm : تم تعريف التابع كـfunction template بنسختين   أولاً - النسخة الافتراضية للتابع : template <class ForwardIterator> ForwardIterator max_element (ForwardIterator first, ForwardIterator last);يعيد التابع مؤشراً للعنصر الأكبر في القائمة التي أول مؤشر لها هو first و مؤشر العنصر بعد الأخير  هو last وأعني بالمؤشر هنا : Iterator إن كنا في container خاص في STL أو عنوان حقيقي إن كنا داخل مصفوفة . هذا التابع الافتراضي يستخدم العملية >operator لمقارنة العناصر , والعنصر الذي لم يعثر على أي عنصر آخر أكبر منه , هو العنصر الأكبر علينا إعادة تعريف العملية >operator إذا أردنا العثور على أكبر عنصر في مجموعة من نوع جديد ( راجع هذا الموضوع للتدرب على إعادة تعريف هذا المعامل )   لنبدأ بالبحث في المصفوفات : الوسيط الأول لهذا التابع هو مؤشر بداية المجال للمصفوفة , علينا إرسال عنوان العنصر المراد البدء بالبحث منه الوسيط الثاني هو مؤشر العنصر بعد الأخير   مثال : لدينا المصفوفة التالية : int A[10]={8,5,7,1,2,4,9,3,4,7};للبحث عن أكبر عنصر في المصفوفة نكتب : max_element(&A[0],&A[10]);الاستدعاء السابق يعيد (((عنوان))) أكبر عنصر ماذا لو أردنا البحث عن أكبر عنصر في المجال من 1 إلى 3 max_element(&A[1],&A[4]);(لا تنس أن الوسيط الثاني هو عنوان العنصر بعد الأخير) يمكننا التعامل مع العناوين مباشرة مثلاً , للعثور على أكبر عنصر في المجال 0 إلى 4 max_element(A,A+5);والشكل السابق أسهل للكتابة من max_element(&A[0],&A[5]);ومفضل عليه دوماً , لأن كتابة [10]A& تعني أننا نصل إلى عنوان عنصر خارج المصفوفة وهذا ليس آمناً . إذا سنعتمد عند استخدامنا للمؤشرات في المصفوفات على ( اسم المصفوفة + الانزياح عن المبدأ ) (ملاحظة : تم استخدام المقارنة المعتادة هنا بين الأعداد لمعرفة العنصر الأكبر )   لنتابع إلى البحث في الحاويات : لدينا الـvector التالي : vector<int> A={8,5,7,1,2,4,9,3,4,7};لإيجاد أكبر عنصر في مجاله كله max_element(A.begin(),A.end());أو يمكننا البدء من begin إلى begin+offset كما يلي : max_element(A.begin(),A.begin()+10);مثلاً إذا أردنا البحث عن أكبر عنصر في المجال من 3 إلى 7 : max_element(A.begin()+3,A.begin()+8);لنقم بإعادة تعريف العملية >operator بالنسبة للنوع الجديد koko المعرف كما يلي struct koko{        int a;        koko(int x):a(x){        }};وسنعيد تعريف المعامل >operator  كما يلي : bool operator<(const koko&first,const koko&second){    if(first.a<=second.a)        return false;    else        return true;}إذا كنت قوي الملاحظة فستعرف أن عملية > الآن تتصرف كما لو كانت عملية < , وهذا يعني أن max_element ستعيد الآن العنصر الأصغر : مثلاً الاستدعاء التالي : max_element(A.begin()+3,A.begin()+8)سيعيد iterator يشير إلى العناصر الأصغر وهو 1 . ماذا تتوقع أن يعيد الاستدعاء التالي : min_element(A.begin()+3,A.begin()+8)أظن أن الفكرة أصبحت واضحةً , فالـ max_element سيعيد العنصر الذي يرجع false عند مقارنته مع جميع العناصر الباقية (أي أنه ليس أصغر من أحد حسب تعريف العملية أصغر ) لنتجه الآن إلى الشكل الآخر للتابع , الشكل المفصل : ثانياً- النسخة المفصلة للتابع : إذا رأينا اننا بحاجة إلى أعادة تعريف العملية > لاستخدام هذا التابع , فربما يكون أكثر وضوحاً ان نستخدم الشكل المفصل للتابع : template <class ForwardIterator, class Compare> ForwardIterator max_element (ForwardIterator first, ForwardIterator last, Compare comp);الوسيط الآخير , هو تابع compare له نفس شكل العملية >operator ويعيد قيمة bool تكون true عندما يكون الوسيط الأول أصغر من الثاني , ولكن لننظر إلى الأمر بشكل مختلف , عندما نبحث عن max_element فالعنصر الذي نعرّفه كـ max هو العنصر الذي يعيد false عندما يتم استدعاء التابع compare ووضعه كوسيط أول مهما كان الوسيط الثاني , وكذلك العنصر الـ min هو العنصر الذي يعيد التابع compare قيمة true إذا كان هو الوسيط الأول مهما يكن الوسيط الثاني (طبعاً في كلا الحالتين نستثني أن يكون الوسيط الثاني هو نفس الوسيط الأول ) لنرجع إلى مثال koko بدلاً من إعادى تعريف العملية > كما يلي : bool operator<(const koko&first,const koko&second){    if(first.a<=second.a)        return false;    else        return true;}سنكتب التابع compare كما يلي : bool compare(const koko&first,const koko&second){    if(first.a<=second.a)        return false;    else        return true;}وسيصبح الاستدعاء كما يلي : max_element(A.begin()+3,A.begin()+8,compare)لاحظ أننا نمرر اسم التابع فقط . يمكننا الآن التخلي عن البنية التغليفية koko (حيث وضعناها فقط لأن إعادة تعريف العملية > بالنسبة لـ int أمر ممنوع) وذلك بفضل التابع compare انظر إلى الكود التالي : #include <iostream>#include <algorithm>#include <vector>using namespace std;bool compare(const int&first,const int&second){    if(first<=second)        return false;    else        return true;}int main(){    vector<int> A={8,5,7,1,2,4,9,3,4,7};    cout<<(*max_element(A.begin()+3,A.begin()+8,compare));    return 0;}مارأيك لو نبحث عن أكبر عدد زوجي ضمن القائمة ؟ كل ما علينا هو تعديل كود التابع compare bool compare(const int&first,const int&second){    if(second%2==0 and first<second)        {            return true;        }    else        return false;}العبارة الفاصلة والتي يجب أن تكون خلاصة هذا المقال هي : يعيد التابع max_element العنصر الذي لا يوجد عنصر أكبر منه , وهذا يعني أن أي مقارنة يكون هو الـ second كوسيط فيها يجب أن تعيد true وأي مقارنة يكون هو الـ first فيها يجب أن تعيد false وذلك واضح من كون عملية المقارنة هي first<second وطالما أنك تحقق هذه العلاقة يمكنك القيام بأي اختبار تريده . ما رأيك بأكبر عدد أولي في القائمة !! واثق من أن الكود التالي سينال إعجابك ! #include <iostream>#include <algorithm>#include <vector>#include <cstdlib>#include <ctime>using namespace std;bool is_prime(const int &x){    for(int i=2;i*i<=x;i++)        if(x%i==0)            return false;    return true;}bool compare(const int&first,const int&second){    if(first<second)        {            if(is_prime(second))                return true;            else                return false;        }    else if(second<first)        {            if(!is_prime(first) and is_prime(second))                return true;            return false;        }    else        return false;}int main(){    vector<int> A={8,5,7,1,2,4,9,3,4,7};    srand(time(0));    for(int i=0;i<100;i++)        A.push_back(rand());    cout<<*max_element(A.begin(),A.end(),compare);    return 0;}ما رأيك بجعله يعيد أقرب عنصر للمتوسّط !! #include <iostream>#include <algorithm>#include <vector>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;int average;bool compare(const int&first,const int&second){    if(abs(first-average)<abs(second-average))        return false;    return true;}int main(){    vector<int> A={8,5,7,1,2,4,9,3,4,7};    srand(time(0));    for(int i=0;i<100;i++)        A.push_back(rand());    average=0;    for(int x:A)        average+=x;    average/=A.size();    cout<<"average = "<<average<<endl;    cout<<*max_element(A.begin(),A.end(),compare);    return 0;}الـ max هو الذي يعيد false كلما كان هو الوسيط الأول ويعيد true كلما كان هو الوسيط الثاني (في تابع المقارنة)   تجدر الإشارة إلى أن جسم التابع هو مشابه لما يلي : template <class ForwardIterator> ForwardIterator max_element ( ForwardIterator first, ForwardIterator last ){ if (first==last) return last; ForwardIterator largest = first; while (++first!=last) if (*largest<*first) // or: if (comp(*largest,*first)) for version (2) largest=first; return largest;}-أخيراً من الأمور التي يجب معرفتها أن بعض البنى لا توفر Forward Iterator مثل stack و queue .. وهذه لا يمكن البحث بداخلها عن أكبر عنصر باستخدام هذا التابع .   المراجع : cpp-reference أسئلة وأمثلة : مثال مباشر وواضح stackoverflow   والله ولي التوفيق
  6. السلام عليكم ورحمة الله وبركاته تعتبر خوارزمية Depth First Search أحد الخوارزميات للمرور على جميع النقاط المتصلة connected nodes في مخطط Graph ما .. لا أريد التكرار فالموضوع عليه الكثير من الشروحات الواضحة على youTube  كما أن صفحة wikipedia فيها شرح ممتاز (وفيديو ملحق لإنشاء متاهة أيضاً :) ) ولكن لتبسيط الأمر .. تخيل أن لدينا شجرة كثيرة الفروع , حتى أن فروعها متداخلة , يعني يمكن أن يتقاطع فرعان ويندمجا ! تخيل أن هذه شجرة : هذه الأشجاء التخيلية التي تحوي فروعاً وتقاطعات تُسمّى Graphs (مخططات ) المهم .. تخيل أننا نريد المرور على جميع فروع الشجرة . سنبدأ من الجذر ونصعد .. ثم سيتفرع الجذع الى عدة فروع .. وكل فرع سيتفرع لاحقاً وهكذا .. هناك عدة طرق يمكننا من خلالها ضمان المرور على جميع الفروع .(المرور على جميع الفروع والتقاطعات(العقد) يُسمّى traversing ) إحداها طريقة Depth first Search تحتاج لتطبيقها إلى مكدّس ومعرفة بسيطة في الحلقات والشروط . خوارزمية DFS : 0-نضع الجذر في المكدس ونبدأ الحلقة طالما أن المكدس غير فارغ : 1- نقوم بوضع علامة على العنصر في قمة المكدس للدلالة على انه قد تمت زيارته 2- نقوم باختبار وجود عناصر مرتبطة بالعنصر الحالي(قمة المكدس ) وهل هي صالحة للزيارة (تكون صالحة للزيارة إن كانت مرتبطة بالعنصر ولم تتم زيارتها من قبل ) 3- كل عنصر يحقق الشرط في الخطوة 2 نضعه في المكدس 4- إن لم يحقق أي عنصر الشرط في الخطوة 2 نقوم بإخراج العنصر الحالي من المكدس 5- ان كان المكدس غير فارغ نذهب للخطوة 1   لنحول الخوارزمية إلى كود نحتاج إلى آلية تكديس وسنستعمل std::stack, وآلية loop ويمكن أن نستعمل for  , وسنحتاج آلية لإعادة القيام بالعملية على العقدة الجديدة (يمكن أن نستعمل العودية recursion ولكن سنطبق اليوم بواسطة حلقة while) كما أننا نحتاج وجود المخطط وبه العقد المتصلة (النقاط المتصلة) وسنستعمل ببساطة مصفوفة من بعدين , كل عنصرين متجاورين فيها يكونان مرتبطين مثال للمصفوفة : 1 2 3 4 5 6 7 8 9 نقول أن 1 مع 4 و 2 مرتبطة , وكذلك :  9 مع 6 و 8 وهكذا (يمكن لك أن تعتبر وجود ارتباطات بالمائل مثل 5 و 9 ان أردت ) يمكننا وضع علامة على النقطة التي تمت زيارتها ببساطة بتغيير قيمة المصفوفة مثلاً من 0 إلى 1 أخيراً  : نلاحظ أن الخطوة 4 لم تعد تحتاج إلى for loop  لأن العقد المرتبطة في حالة المصفوفة هي 4 كحد أقصى لذلك سنكتبها يدوياً   لنبدأ ..على بركة الله تحويل الخوارزمية إلى كود : أولا ودوماً أولاً : تطبيق بنية الـGraph ببساطة مصفوفة يمكن ان تحوي 0 أو 1 .. bool :) bool graph[30][30]={false}; القيمة false تعني أننا لم نزر أي عقدة بعد . ثانياً : كيفية الامساك بعقدة ما .. في حالتنا عن طريق الموضع في المصفوفة سنكتب  struct بسيط يُمثّل الموضع struct coord{     int x;     int y;     coord(int x1,int y1){         x=x1;         y=y1;     } }; ولا ننسى آلية التكديس stack <coord> s;والآن  الحلقة التي سنعمل بداخلها الخطوات من 1 إلى 5 , وبها سنتابع بقية العمل , ولكن قبل الدخول إليها علينا دفع الجذر إلى المكدس (أو أي عقدة نرغب في البدء منها ) while(!s.empty()){ }سنقوم بملء التابع السابق كما توضّح الخوارزمية   1-عملية وضع علامة على الفرع الذي تمت زيارته         graph[s.top().y][s.top().x]=true;2-اختبار صلاحية زيارة جميع العقد المرتبطة , وبعد انتهاء العقد المرتبطة ( أو عدم وجودها فالأمر سيان ) أخرج العقدة الحالية من stack سنختبر كل جهة على حدة كما يلي: //look at left        if(valid(s.top().y,s.top().x-1)){            s.push(coord(s.top().y,s.top().x-1));        }        //look at right        else if(valid(s.top().y,s.top().x+1)){            s.push(coord(s.top().y,s.top().x+1));        }        //look up        else if(valid(s.top().y-1,s.top().x)){            s.push(coord(s.top().y-1,s.top().x));        }        //look down        else if(valid(s.top().y+1,s.top().x)){            s.push(coord(s.top().y+1,s.top().x));        }        else{            s.pop();        }الكود بصيغته النهائية : الكود : أولاً : البنى والتوابع المساعدة struct coord{    int x;    int y;    coord(int y1,int x1){        x=x1;        y=y1;    }};const int X=10,Y=10;bool graph[Y][X]={false};stack <coord> s;bool valid(int y,int x){    if(x<X&&x>=0)        if(y<Y&&y>=0)            if(graph[y][x]==false)                return true;    return false;}والتنفيذ في الدالةmain int main(){    //push the current node    s.push(coord(0,0));    while(!s.empty())    {        graph[s.top().y][s.top().x]=true;        //look at left        if(valid(s.top().y,s.top().x-1)){            s.push(coord(s.top().y,s.top().x-1));        }        //look at right        else if(valid(s.top().y,s.top().x+1)){            s.push(coord(s.top().y,s.top().x+1));        }        //look up        else if(valid(s.top().y-1,s.top().x)){            s.push(coord(s.top().y-1,s.top().x));        }        //look down        else if(valid(s.top().y+1,s.top().x)){            s.push(coord(s.top().y+1,s.top().x));        }        else{            s.pop();        }    }    return 0;}كي نتابع عملية السير سنكتب تابع بسيط لإظهار المخطط بعد كل تغيير هذا مثال void printGraph(){/*Put here any implementation to return the pointer to top left*/        cout << s.size() << " " << s.top().x <<" " <<s.top().y<< endl;    for(int i=0;i<Y;i++)    {        for(int j=0;j<X;j++)        {            cout<<(graph[i][j]?'#':' ');        }        cout <<endl;    }/*Put here any implementation to Sleep for 10-100 milli second*/    }في ويندوز سأستعمل تابعين من الـ API void printGraph(){    COORD topLeft={0,0};    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),topLeft);    cout << s.size() << " " << s.top().x <<" " <<s.top().y<< "     " << endl;    for(int i=0;i<Y;i++)    {        for(int j=0;j<X;j++)        {            cout<<(graph[i][j]?' ':'#');        }        cout <<endl;    }    Sleep(30);}ثم ضع استدعاء التابع داخل حلقة while الخاصة بالخوارزمية جرب الكود التالي  في ويندوز (++C) #include<stack>#include<iostream>#include<windows.h>using std::stack;using std::cout;using std::endl;struct coord{    int x;    int y;    coord(int y1,int x1){        x=x1;        y=y1;    }};const int X=10,Y=10;bool graph[Y][X]={false};stack <coord> s;void printGraph(){    COORD topLeft={0,0};    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),topLeft);    cout << s.size() << " " << s.top().x <<" " <<s.top().y<< "     " << endl;    for(int i=0;i<Y;i++)    {        for(int j=0;j<X;j++)        {            cout<<(graph[i][j]?' ':'#');        }        cout <<endl;    }    Sleep(30);}bool valid(int y,int x){    if(x<X&&x>=0)        if(y<Y&&y>=0)            if(graph[y][x]==false)                return true;    return false;}int main(){    //put flag on the visited node    int x=0,y=0;    //push the current node    s.push(coord(x,y));    while(!s.empty())    {        printGraph();        graph[s.top().y][s.top().x]=true;        //look at left        if(valid(s.top().y,s.top().x-1)){            s.push(coord(s.top().y,s.top().x-1));        }        //look at right        else if(valid(s.top().y,s.top().x+1)){            s.push(coord(s.top().y,s.top().x+1));        }        //look up        else if(valid(s.top().y-1,s.top().x)){            s.push(coord(s.top().y-1,s.top().x));        }        //look down        else if(valid(s.top().y+1,s.top().x)){            s.push(coord(s.top().y+1,s.top().x));        }        else{            s.pop();        }    }    return 0;}  تجدر الإشارة إلى فكرة هامّة جداً .. يعتمد المعالج في استدعاء التوابع على مكدّس خاص بالاستدعاءات ويمكننا الاستغناء عن مكدسنا std::stack والاستعانة بالمكدس الخاص بالاستعداءات وذلك عن طريق وضع العملية في تابع بدلاً من while , وبدلاً من عملية push سنقوم باستدعاء التابع مرة أخرى , وبمجرد انتهاء التابع أو عمل return  سيتم عمل pop للقيمة الحالية انظر الكود التالي(أبسط من السابق) #include<iostream>#include<windows.h>using std::cout;using std::endl;const int X=10,Y=10;bool graph[Y][X]={false};void printGraph(){    COORD topLeft={0,0};    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),topLeft);    for(int i=0;i<Y;i++)    {        for(int j=0;j<X;j++)        {            cout<<(graph[i][j]?' ':'#');        }        cout <<endl;    }    Sleep(30);}bool valid(int y,int x){    if(x<X&&x>=0)        if(y<Y&&y>=0)            if(graph[y][x]==false)                return true;    return false;}void function(int y,int x){    printGraph();    graph[y][x]=true;    //look at left    if(valid(y,x-1)){        //s.push(coord(s.top().y,s.top().x-1));        function(y,x-1);    }    //look at right    if(valid(y,x+1)){        //s.push(coord(s.top().y,s.top().x+1));        function(y,x+1);    }    //look up    if(valid(y-1,x)){        //s.push(coord(s.top().y-1,s.top().x));        function(y-1,x);    }    //look down    if(valid(y+1,x)){        //s.push(coord(s.top().y+1,s.top().x));        function(y+1,x);    }//        s.pop();        return ;}int main(){    function(0,0);    return 0;}ولكننا خسرنا ميزة تتبع المكدس فلم يعد بإمكاننا مثلاً كتابة cout << s.size() << " " << s.top().x <<" " <<s.top().y<< "     " << endl;إذا جربت الكود , فستلاحظ أنه يسير بطريقة عادية ليمر على جميع عناصر المصفوفة , ولكن جرب كتابة  function(5,5);وسيبدأ من المنتصف , وعندها ستلاحظ سلوكاً غير متوقع (ربما) في المرور على جميع العناصر .   والآن إلى إنشاء المتاهة: ببساطة سنتحرك خطوتين بدلاً من خطوة واحدة , وبذلك سنترك فراغات تُشكّل الحوائط ! #include<cstdio>#include<windows.h>const int X=21,Y=21;bool graph[Y][X]={false};void printGraph(){    COORD topLeft={0,0};    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),topLeft);    for(int i=0;i<Y;i++)    {        for(int j=0;j<X;j++)        {            putchar(graph[i][j]?' ':'#');        }        putchar('\n');    }}bool valid(int y,int x){    if(x<X&&x>=0)        if(y<Y&&y>=0)            if(graph[y][x]==false)                return true;    return false;}void function(int y,int x){    printGraph();    //look at left    if(valid(y,x-2)){        //s.push(coord(s.top().y,s.top().x-1));        graph[y][x-1]=true;        graph[y][x-2]=true;        function(y,x-2);    }    //look at right    if(valid(y,x+2)){        //s.push(coord(s.top().y,s.top().x+1));        graph[y][x+1]=true;        graph[y][x+2]=true;        function(y,x+2);    }    //look up    if(valid(y-2,x)){        //s.push(coord(s.top().y-1,s.top().x));        graph[y-1][x]=true;        graph[y-2][x]=true;        function(y-2,x);    }    //look down    if(valid(y+2,x)){        //s.push(coord(s.top().y+1,s.top().x));        graph[y+1][x]=true;        graph[y+2][x]=true;        function(y+2,x);    }//        s.pop();        return ;}int main(){    function(5,5);    Sleep(100000);    return 0;}جرب الكود , وستلاحظ أن المتاهة سهلة جداً  للحل ولجعلها صعبة وعشوائية سنغير فقط طريقة الرؤية للكود ! ماذا يعني هذا ؟ يعني أن نجعل اختبارات (اليسارواليمين .. ) غير ثابته , فمثلاً يمكن أن نختبر المرور للأسفل قبل اليمين وهكذا .. لاحظ اختلافات الكود : #include<cstdio>#include<cstdlib>#include<ctime>#include<windows.h>const int X=31,Y=31;bool graph[Y][X]={false};void printGraph(){    COORD topLeft={0,0};    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),topLeft);    for(int i=0;i<Y;i++)    {        for(int j=0;j<X;j++)        {            putchar(graph[i][j]?' ':'#');        }        putchar('\n');    }}bool valid(int y,int x){    if(x<X&&x>=0)        if(y<Y&&y>=0)            if(graph[y][x]==false)                return true;    return false;}void function(int y,int x){    printGraph();    for(int i=0;i<10;i++){//to ensure passing all valid moves        int dx=0,dy=0;        while(dx^dy==0){            dy=rand()%2;//zero or one            dx=rand()%2;//zero or one        }        if(rand()%2==1)            dx*=-1,            dy*=-1;        if(valid(y+2*dy,x+2*dx)){            //s.push(coord(s.top().y,s.top().x-1));            graph[y+dy][x+dx]=true;            graph[y+2*dy][x+2*dx]=true;            function(y+2*dy,x+2*dx);        }    }        return ;}int main(){    srand(time(0));    function(5,5);    Sleep(100000);    return 0;{في الختام أود لفت الانتباه إلى أنه من الأمور الهامة جداً عند دراسة الخوارزميات عدم خلط الخورازمية بالتطبيق , مثلاً فتطبيق رسم المتاهة هو أحد التطبيقات لخوارزمية DFS وليس هو الخوارزمية , وقد وضعته كمثال رسومي جيد لبيان جمال الخوارزمية ليس أكثر .   والله ولي التوفيق
  7. السلام عليكم ورحمة الله وبركاته...... هلأ انا عملت كود سيرش وبدي أخد ID من اليوزر وأخليه يرجعلي object من customerالمشكلة انو السيرش راح يكون في ال binary tree int BST::BSTSearch(Employee e){ Node *locptr=root; int found=0; for(;;) { if(found||locptr==NULL) break; else if(e.getID()<locptr->data->getID()) locptr=locptr->left; else if(e.getID()<locptr->data->getID()) locptr=locptr->right; else found=1; } return found;}وجزاكم الله خيرا