كيفية الكشف عن حلقة لا نهائية في العودية الاتصال ؟

StackOverflow https://stackoverflow.com/questions/1030527

  •  06-07-2019
  •  | 
  •  

سؤال

لدي وظيفة بشكل متكرر تطلق على نفسها و أريد أن كشف وإنهاء إذا كان يذهب في حلقة لا نهائية ، هـ - الحصول دعا نفس المشكلة مرة أخرى.ما هي أسهل طريقة للقيام بذلك ؟

تحرير:هذه هي وظيفة ما كان يسمى بشكل متكرر مع مختلف قيم x و y.أريد إنهاء إذا كان في مكالمة العودية ، قيمة الزوج (x,y) تتكرر.

int fromPos(int [] arr, int x, int y)
هل كانت مفيدة؟

المحلول

وإذا كانت وظيفة وظيفية بحتة، أي أنه ليس له أي آثار الدولة أو الجانب، ثم هل يمكن الحفاظ على Set من الحجج (تحرير: رؤية تحرير الخاص بك، فإنك سوف تحتفظ مجموعة من أزواج من (س، ص)) أن وقد دعا إليها، وفي كل مرة فقط معرفة ما اذا كان حجة الحالية في المجموعة. بهذه الطريقة، يمكنك الكشف عن دورة إذا قمت بتشغيل إلى ذلك بسرعة كبيرة. ولكن إذا كان الفضاء حجة كبيرة ويستغرق وقتا طويلا للحصول على تكرار، قد نفدت الذاكرة الخاص بك قبل الكشف عن دورة. بشكل عام، وبطبيعة الحال، لا يمكنك أن تفعل ذلك لأن هذا هو مشكلة وقف.

نصائح أخرى

ويتمثل أحد السبل لتمرير متغير depth من مكالمة واحدة إلى أخرى، تزايد في كل مرة تدعو الدالة نفسها. تأكد من أن depth لا تنمو أكبر من بعض عتبة معينة. مثال:

int fromPos(int [] arr, int x, int y)
{
    return fromPos(arr, x, y, 0);
}

int fromPos(int [] arr, int x, int y, int depth)
{
    assert(depth < 10000);

    // Do stuff

    if (condition)
        return fromPos(arr, x+1, y+1, depth + 1);
    else
        return 0;
}

وسوف تحتاج إلى العثور على عمل حول، لأنه كما كنت قد طلبت ذلك، لا يوجد حل عام. انظر مشكلة وقف للحصول على مزيد من المعلومات.

وطريقة سهلة سيكون لتنفيذ أحد الإجراءات التالية:

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

وتمرير المتغير للإشارة إلى عدد المرات التي تم استدعاء الدالة، وبشكل تعسفي يحد من عدد المرات التي يمكن أن يطلق عليه.

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

ويمكنك إما استخدام الزائد للتوقيع ثابت (وهذا هو أفضل طريقة)، أو يمكنك استخدام متغير ثابت:

int someFunc(int foo)
{
    static recursionDepth = 0;
    recursionDepth++;
    if (recursionDepth > 10000)
    {
        recurisonDepth = 0;
        return -1;
    }
    if (foo < 1000)
        someFunc(foo + 3);
    recursionDepth = 0;
    return foo;
}

والجواب جون Kugelman مع الحمولة الزائدة هي أفضل في نتيجة انها موضوع آمن، في حين المتغيرات ثابتة ليست كذلك.

وBilly3

ويبدو أنك قد تعمل على مجموعة 2D. إذا كنت قد حصلت على الجزء الضئيل لتجنيب في قيم المصفوفة، يمكنك استخدامه بمثابة العلم. التحقق من ذلك، وإنهاء العودية إذا تم تعيين العلم. ثم تعيينها قبل أن يسافرا.

إذا لم يكن لديك قليلا لقطع الغيار في القيم، يمكنك دائما أن مجموعة من الأشياء بدلا من ذلك.

إذا كنت تريد أن تبقي توقيع الأسلوب الخاص بك، هل يمكن أن تبقى بضع مجموعات لتسجيل القيم القديمة x و y.

static Set<Integer> xs;
static Set<Integer> ys;//Initialize this!
static int n=0;//keeps the count function calls.

int fromPos(int [] arr, int x, int y){

 int newX= getX(x);
 int newY= getY(y);
 n++; 
 if ((!xs.add(Integer.valueOf(newX)) && !ys.add(Integer.valueOf(newY))){

   assert(n<threshold); //threshold defined elsewhere.
   fromPos(arr,newx,newy);
 }
}

وIMHO حلقات فقط يمكن أن تذهب في حلقة لا نهائية.

إذا طريقة لديه مستوى العديد جدا من العودية وJVM سوف رمي StackOverflowError. يمكنك فخ هذا الخطأ مع كتلة حاول / الصيد والقيام بكل ما كنت تنوي القيام به عند حدوث مثل هذه الحالة.

وظيفة متكررة تنتهي في حالة الشرط.

أمثلة:

  • نتيجة وظيفة 0 أو هو 1
  • أقصى عدد من المكالمات يتم التوصل إلى
  • والنتيجة هي أقل/أكبر من قيمة المدخلات

في حالة الشرط ([x0,y0] == [xN,yN]) OR ([x1,y1] == [xN,yN]) OR ([xN-1,yN-1] == [xN,yN])

0, 1, ...N هي مؤشرات من أزواج

وبالتالي تحتاج حاوية(ناقلات, قائمة, خريطة) لتخزين السابقة أزواج ومقارنتها الحالية الزوج.

والأولى findbugs استخدام mvn: واجهة المستخدم الرسومية لفتح واجهة المستخدم الرسومية التي تشير إلى السطر حيث وجود هذا الخطأ

وأنا أيضا واجهت نفس المشكلة وحلها I بإضافة متغير منطقية في التحقق حلقة.

ورمز من قبل ->

for (local = 0; local < heightOfDiv; local = local + 200) { // Line under Error
          tileInfo = appender.append(tileInfo).append(local).toString();
          while (true) {
            try {
              tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
              incr++;
            } catch (Exception e) {
              incr = 1;
              tileInfo = appender.append(tileInfo).append("/n").toString();
            }
          }

لحل هذه المشكلة، أنا فقط واضاف متغير منطقية وتعيينه إلى false في كتلة الصيد. تحقق عليه

for (local = 0; local < heightOfDiv; local = local + 200) {
          tileInfo = appender.append(tileInfo).append(local).toString();
          boolean terminationStatus = true;
          while (terminationStatus) {
            try {
              tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
              incr++;
            } catch (Exception e) {
              incr = 1;
              tileInfo = appender.append(tileInfo).append("/n").toString();
              terminationStatus = false;
            }
          }

وهذه هي الطريقة التي أنا تحل هذه المشكلة. نأمل أن يكون هذا سوف يساعد. :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top