سؤال

بعد أن اقتنعت بأن الفواصل/الاستمرارات المسمى هي "nono" كاملة هنا, ، أحتاج إلى مساعدة لإزالة الملصق من الكود الخاص بي.

لدي مصفوفة مربعة ومتجه لهما نفس الطول.يحتوي المتجه بالفعل على بعض القيم، اعتمادًا على القيم الموجودة في المصفوفة، يتم تغيير المتجه في الحلقة.

آمل أن يكون جزء التعليمات البرمجية مفهومًا بشكل أساسي ...

vectorLoop:
for( int idx = 0; idx < vectorLength; idx++) {
    if( conditionAtVectorPosition( v, idx ) ) continue vectorLoop;

    matrixLoop:
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue matrixLoop;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) continue vectorLoop;
    }
    setValueInVector( v, idx );
}     

من فضلك أقنعني أن هناك نسخة أكثر قابلية للقراءة/أفضل بدون التسميات.

هل كانت مفيدة؟

المحلول

النظر في الحلول المقدمة حتى الآن:

  • تبدو جميعها أقل قابلية للقراءة من النسخة الأصلية، حيث أنها تتضمن إنفاق المزيد من التعليمات البرمجية على آلية التعليمات البرمجية بدلاً من إنفاقها على الخوارزمية نفسها

  • وبعضها مكسور، أو كان قبل أن يتم تحريرها.الأمر الأكثر إزعاجًا هو حقيقة أنه يتعين على الناس التفكير مليًا في كيفية كتابة الكود بدون تسميات وعدم كسر أي شيء.

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

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

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

نصائح أخرى

@Patrick أنت تفترض الاتصال بـ setValueInVector( v, idx );في نهاية الحلقة الثانية على ما يرام.إذا كان الكود متطابقًا، فمن المنطقي أنه يجب إعادة كتابته إلى شيء مثل هذا:

for( int idx = 0; idx 

بسهولة يا رجل طيب.

for( int idx = 0; idx < vectorLength; idx++) {
  if( conditionAtVectorPosition( v, idx ) ) continue;

  for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
    if( anotherConditionAtVector( v, rowIdx ) ) continue;
    if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) break;
  }
  if( !conditionAtMatrixRowCol( m, rowIdx, idx ) )
    setValueInVector( v, idx );
}

يحرر:صحيح تماما أنت أندرس.لقد قمت بتحرير الحل الخاص بي لأخذ ذلك في الاعتبار أيضًا.

من قراءة التعليمات البرمجية الخاصة بك.

  • لقد لاحظت أنك قمت بإزالة مواضع المتجهات غير الصالحة في conditionAtVectorPosition ثم قمت بإزالة الصفوف غير الصالحة في AnotherConditionAtVector.
  • يبدو أن التحقق من الصفوف في AnotherConditionAtVector أمر زائد عن الحاجة لأنه مهما كانت قيمة idx، فإن AnotherConditionAtVector يعتمد فقط على فهرس الصف (على افتراض أن AnotherConditionAtVector ليس له أي آثار جانبية).

لذلك يمكنك القيام بذلك:

  • احصل على المواضع الصالحة أولاً باستخدام conditionAtVectorPosition (هذه هي الأعمدة الصالحة).
  • ثم احصل على الصفوف الصالحة باستخدام AnotherConditionAtVector.
  • وأخيرًا، استخدم conditionAtMatrixRowCol باستخدام الأعمدة والصفوف الصالحة.

آمل أن يساعد هذا.

@نيكولاس

وبعضها مكسور، أو كان قبل أن يتم تحريرها.الأكثر ملعظة هي حقيقة أن الناس يتعين عليهم التفكير بجد حول كيفية كتابة الكود بدون ملصقات وعدم كسر أي شيء.

عندي وجهة نظر مختلفة:بعضها مكسور لأنه من الصعب معرفة سلوك الخوارزمية الأصلية.

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

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

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

أعتقد أن السؤال كان حول كيفية إزالة التصنيفات، وليس كيفية تحسين الخوارزمية.يبدو لي أن الناشر الأصلي لم يكن على علم بكيفية استخدام الكلمات الرئيسية "متابعة" و"فاصل" بدون تصنيفات، ولكن بالطبع، قد تكون افتراضاتي خاطئة.

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

ومع ذلك، فإن إجراء نفس الاختبار مرتين ليس هو الحل الأمثل من الناحية النظرية.

يحرر:في فكرة ثانية، المثال ليس في الواقع استخدامًا سيئًا للمسميات.وأنا أوافق على ذلك "goto هو لا لا", ، ولكن ليس بسبب رمز مثل هذا.استخدام التسميات هنا لا يؤثر فعليًا على سهولة قراءة الكود بطريقة مهمة.بالطبع، فهي ليست مطلوبة ويمكن حذفها بسهولة، ولكن عدم استخدامها لمجرد أن "استخدام التصنيفات أمر سيء" ليس حجة جيدة في هذه الحالة.بعد كل شيء، إزالة التسميات لا تجعل قراءة الكود أسهل بكثير، كما علق آخرون بالفعل.

لم يكن هذا السؤال يتعلق بتحسين الخوارزمية - ولكن شكرًا على أي حال؛-)

في الوقت الذي كتبته، كنت أعتبر الاستمرار المسمى حلاً قابلاً للقراءة.

سألت SO أ سؤال حول الاصطلاح (وجود الملصق بأحرف كبيرة أم لا) للتسميات في Java.

في الأساس، كانت كل إجابة تقول لي "لا تستخدمها - هناك دائمًا طريقة أفضل!معيد البناء!".لذلك قمت بنشر هذا السؤال لأطلب حلاً أكثر قابلية للقراءة (وبالتالي أفضل؟).

وحتى الآن لست مقتنعاً تماماً بالبدائل المطروحة حتى الآن.

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

لكن في حالتي، تكون الاختبارات الشرطية بسيطة جدًا والخوارزمية مأخوذة من ورقة رياضية، وبالتالي من المحتمل جدًا ألا تتغير في المستقبل القريب.لذلك أفضل أن تكون جميع الأجزاء ذات الصلة مرئية مرة واحدة بدلاً من الاضطرار إلى التمرير إلى طريقة أخرى تسمى شيئًا مثل checkMatrixAtRow(x).

خاصة في الخوارزميات الرياضية الأكثر تعقيدًا، أجد أنه من الصعب جدًا العثور على أسماء وظائف "جيدة" - ولكن أعتقد أن هذا سؤال آخر

أعتقد أن الحلقات المُصنفة غير شائعة جدًا بحيث يمكنك اختيار أي طريقة لتصنيفها تناسبك - ما لديك هناك يجعل نواياك مع الاستمرار واضحة تمامًا.


بعد توجيه الاتهام لاقتراح إعادة بناء الحلقات في السؤال الأصلي ورؤية الكود المعني الآن، أعتقد أن لديك حلقة سهلة القراءة هناك.

ما كنت أتخيله كان جزءًا مختلفًا تمامًا من التعليمات البرمجية - عند عرض المثال الفعلي، أستطيع أن أرى أنه أنظف بكثير مما كنت أعتقد.

أعتذر عن سوء الفهم.

هل هذا العمل بالنسبة لك؟لقد قمت باستخراج الحلقة الداخلية إلى طريقة CheckedEntireMatrix (يمكنك تسميتها أفضل مني) - كما أن جافا الخاصة بي صدئة بعض الشيء ..ولكن أعتقد أنه يوصل الرسالة

for( int idx = 0; idx < vectorLength; idx++) {
    if( conditionAtVectorPosition( v, idx ) 
    || !CheckedEntireMatrix(v)) continue;

    setValueInVector( v, idx );
}

private bool CheckedEntireMatrix(Vector v)
{
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
    }   
    return true;
}

لدى Gishu الفكرة الصحيحة:

for( int idx = 0; idx < vectorLength; idx++) {
    if (!conditionAtVectorPosition( v, idx ) 
        && checkedRow(v, idx))
         setValueInVector( v, idx );
}

private boolean checkedRow(Vector v, int idx) {
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
    }  
    return true;
}

لست متأكدًا من فهم المتابعة الأولى.سأقوم بنسخ Gishu وأكتب شيئًا مثل (آسف إذا كانت هناك بعض الأخطاء):

for( int idx = 0; idx < vectorLength; idx++) {
    if( !conditionAtVectorPosition( v, idx ) && CheckedEntireMatrix(v))
        setValueInVector( v, idx );
}

inline bool CheckedEntireMatrix(Vector v) {
    for(rowIdx = 0; rowIdx < n; rowIdx++)
        if ( !anotherConditionAtVector(v,rowIdx) && conditionAtMatrixRowCol(m,rowIdx,idx) ) 
            return false;
    return true;
}

@سادي:

تبدو جميعها أقل قابلية للقراءة من النسخة الأصلية، حيث أنها تتضمن إنفاق المزيد من التعليمات البرمجية على آلية التعليمات البرمجية بدلاً من إنفاقها على الخوارزمية نفسها

إن إضفاء الطابع الخارجي على الحلقة الثانية خارج الخوارزمية ليس بالضرورة أقل قابلية للقراءة.إذا تم اختيار اسم الطريقة جيدًا، فيمكن أن يؤدي ذلك إلى تحسين إمكانية القراءة.

وبعضها مكسور، أو كان قبل أن يتم تحريرها.الأمر الأكثر إزعاجًا هو حقيقة أنه يتعين على الناس التفكير مليًا في كيفية كتابة الكود بدون تسميات وعدم كسر أي شيء.

عندي وجهة نظر مختلفة:بعضها معطل لأنه من الصعب معرفة سلوك الخوارزمية الأصلية.

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

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

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

أنا لا أرى هذه النقطة.نعم، إنه لا يغير السلوك، مثل...إعادة بناء التعليمات البرمجية؟

من المؤكد أن هناك حالات يتم فيها استخدام الملصقات بشكل غير صحيح ويجب إعادة هيكلتها.أنا لا أعتقد أنه ينبغي التعامل معها على أنها قاعدة غير قابلة للكسر.

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

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