سؤال

مارتن فاولر لديه فئة المال التي لديها روتين تخصيص الأموال. يخصص هذا الروتين المال وفقا لقائمة معينة من النسب دون أن تفقد أي قيمة من خلال التقريب. ينتشر أي قيمة بقية على النتائج.

على سبيل المثال، سيؤدي 100 دولار مخصصا من قبل "النسب" (1، 1، 1) (34 دولارا، 33 دولارا، 33 دولارا).

هنا هو allocate وظيفة:

public long[] allocate(long amount, long[] ratios) {
    long total = 0;
    for (int i = 0; i < ratios.length; i++) total += ratios[i];

    long remainder = amount;
    long[] results = new long[ratios.length];
    for (int i = 0; i < results.length; i++) {
        results[i] = amount * ratios[i] / total;
        remainder -= results[i];
    }

    for (int i = 0; i < remainder; i++) {
        results[i]++;
    }

    return results;
}

(من أجل هذا السؤال، لجعلها أكثر بساطة، لقد أخذت حرية استبدال أنواع المال مع أوقات طويلة.)

السؤال هو، كيف أعرف أنه صحيح؟ كل شيء يبدو بديهيا إلى حد كبير باستثناء النهائي للنتيجة. أعتقد أنه لإثبات الوظيفة صحيحة، فسيكون ذلك كافيا لإثبات أن العلاقة التالية صحيحة في النهائي للنتيجة:

remainder < results.length

يمكن لأي شخص أن يثبت ذلك؟

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

المحلول

البصيرة الرئيسية هي أن ما تبقى إجمالي يساوي مجموع الأبقان عند حساب كل منهما result[i].

نظرا لأن كل باقي فردي هو نتيجة التقريب، فهي على الأكثر 1. هناك results.length مثل هذه البقية، وبالتالي فإن ما تبقى إجمالي هو على الأكثر results.length.

تعديل: من الواضح أنه ليس دليلا دون بعض الرموز الجميلة، لذلك هنا بعض ...
alt text

نصائح أخرى

لا يوجد دليل مطلوب.

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

الباقي يحتوي على المبلغ غير المخصص. والتي ستكون دائما عدد صحيح أقل من "أنا". لذلك يعطي ببساطة كل جهاز استقبال 1 حتى يختفي الأموال.

بسيط

فقط استخدم حقيقة ذلك

أ = الكلمة (A / B) * B + (٪ ب)

أود أن أقول أنه غير صحيح لأن بعض النسبة الغريبة يمكن أن تسبب باقي أكبر ثم عدد النتائج. لذلك أقترح results[i % results.length].amount++;.

تحرير: أنا سحب إجابتي. مع وجود نسبة فضولية لا توجد نسبة فضولية ومعدلو نقطة عائمة لا يساعد

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