ما يسمى النموذج العددي هو إضافة فاصلة بين كل ثلاثة أرقام تبدأ من أرقام واحدة. على سبيل المثال ، "10000". لمعالجة هذا المطلب ، كتبت في البداية وظيفة مثل هذا:
نسخة الكود كما يلي:
// الطريقة 1
وظيفة tothologs (num) {
var result = [] ، counter = 0 ؛
num = (num || 0) .ToString (). split ('') ؛
لـ (var i = num.length-1 ؛ i> = 0 ؛ i--) {
Counter ++ ؛
النتيجة. unshift (num [i]) ؛
if (! (counter ٪ 3) && i! = 0) {result.unshift ('،') ؛ }
}
return result.join ('') ؛
}
تتمثل عملية تنفيذ الطريقة الأولى في تحويل الأرقام إلى سلاسل ، وكسرها إلى صفيف ، ثم تبدأ من النهاية ، إدراج العناصر الموجودة في الصفيف إلى بداية الصفيف الجديد (النتيجة). في كل مرة يتم فيها إدخال عنصر ، يحسب العداد الرقم (إضافة 1). عندما يكون العداد مضاعفًا من 3 ، يتم إدخال فاصلة ، ولكن كن حذرًا من عدم وجود فاصلة مطلوبة في البداية (عندما أكون 0). أخيرًا ، يتم الحصول على النتيجة عن طريق استدعاء طريقة الانضمام للمصفوفة الجديدة.
كانت الطريقة أكثر وضوحًا وأسهل في الفهم ، وتم استخدامها أيضًا في المشروع لفترة من الوقت. لكن الحدس يخبرني أنه لا يعمل بشكل جيد.
الطريقة 2 - إصدار سلسلة الطريقة 1
نسخة الكود كما يلي:
// الطريقة 2
وظيفة tothologs (num) {
var result = '' ، counter = 0 ؛
num = (num || 0) .ToString () ؛
لـ (var i = num.length-1 ؛ i> = 0 ؛ i--) {
Counter ++ ؛
النتيجة = num.charat (i) + النتيجة ؛
if (! (counter ٪ 3) && i! = 0) {result = '،' + result ؛ }
}
نتيجة العودة
}
الطريقة 2 هي نسخة محسّنة من الطريقة 1. إنها لا تقسم الأوتار إلى صفائف ، وتعمل دائمًا على الأوتار.
الطريقة 3 - تتطابق حلقة الأرقام الثلاثة في النهاية
نسخة الكود كما يلي:
// الطريقة 3
وظيفة tothologs (num) {
var num = (num || 0) .ToString () ، re = // d {3} $/، result = '' ؛
بينما (re.test (num)) {
النتيجة = regexp.lastmatch + نتيجة ؛
if (num! == regexp.lastmatch) {
النتيجة = '،' + النتيجة ؛
num = regexp.leftContext ؛
} آخر {
num = '' ؛
استراحة؛
}
}
if (num) {result = num + result ؛ }
نتيجة العودة
}
الطريقة 3 هي خوارزمية مختلفة تمامًا. تتم مطابقة الأرقام الثلاثة في النهاية من خلال حلقة تعبير منتظمة. في كل مرة يتم فيها مطابقة المباراة ، يتم إدراج الفاصلة والمحتوى المطابق في بداية سلسلة النتائج ، ثم يتم تعيين الهدف المطابق (NUM) للمحتوى الذي لم يتطابق بعد (regexp.leftcontext). بالإضافة إلى ذلك ، يرجى ملاحظة:
1. إذا كان عدد الأرقام مضاعفًا من 3 ، فيجب أن تكون المباراة الأخيرة ثلاثة أرقام ، ولكن ليست هناك حاجة لإضافة فاصلة قبل الأرقام الثلاثة الأولى ؛
2. إذا لم يكن عدد أجزاء الرقم ليس مضاعفًا من 3 ، فسيحصل متغير NUM بالتأكيد على 1 إلى 2 أرقام في النهاية. بعد الحلقة ، يجب إدخال الأرقام المتبقية في بداية سلسلة النتائج.
على الرغم من أن الطريقة الثالثة تقلل من عدد الحلقات (تتم معالجة ثلاثة أحرف في وقت واحد) ، يتم زيادة الاستهلاك إلى حد ما بسبب استخدام التعبيرات العادية.
الطريقة 4 - إصدار سلسلة الطريقة 3
نسخة الكود كما يلي:
// الطريقة 4
وظيفة tothologs (num) {
var num = (num || 0) .ToString () ، result = '' ؛
بينما (num.length> 3) {
النتيجة = '،' + num.slice (-3) + النتيجة ؛
num = num.slice (0 ، num.length - 3) ؛
}
if (num) {result = num + result ؛ }
نتيجة العودة
}
في الواقع ، يمكن تحقيق وظيفة اعتراض الأحرف الثلاثة الأخيرة من خلال طريقة الشريحة أو الفرعية أو السلسلة الفرعية لنوع السلسلة. هذا يتجنب التعبيرات العادية.
الطريقة 5 - طريقة الجمع والتقارب
نسخة الكود كما يلي:
// الطريقة 5
وظيفة tothologs (num) {
var num = (num || 0) .ToString () ، temp = num.length ٪ 3 ؛
التبديل (temp) {
الحالة 1:
num = '00' + num ؛
استراحة؛
الحالة 2:
num = '0' + num ؛
استراحة؛
}
إرجاع num.match (// d {3}/g). join ('،'). استبدال (/^0+/، '') ؛
}
أولاً ، قم بتكوين عدد الأرقام في مضاعفات 3 ، وقم بقطعها إلى مجموعات من كل ثلاثة أرقام من خلال التعبيرات العادية ، ثم أضف فواصل من خلال طريقة الانضمام ، وأخيراً قم بإزالة مكملة 0.
الطريقة 6 - طريقة كسول
نسخة الكود كما يلي:
// الطريقة 6
وظيفة tothologs (num) {
return (num || 0) .ToString (). استبدال (/(/d) (؟ = (؟:/d {3})+$)/g ، '$ 1 ،') ؛
}
أشعر دائمًا أنه يمكن إجراء هذا التنسيق من خلال استبدال تعبير منتظم ، لكنني بحاجة إلى استخدام التأكيدات وطرق الكتابة الأخرى ، لكنني لست على دراية بهذا الجزء. بعد غوغل ، وجدت مثل هذا التعبير العادي ، والذي ربما يكون أقصر تطبيق للرمز.
نتائج الاختبار
| رقم | الوقت الذي يقضيه على 5000 مرة (MS) | |||||
|---|---|---|---|---|---|---|
| الطريقة 1 | الطريقة 2 | الطريقة 3 | الطريقة 4 | الطريقة 5 | الطريقة 6 | |
| 1 | 4 | 1 | 3 | 1 | 14 | 2 |
| 10 | 14 | 1 | 3 | 0 | 7 | 2 |
| 100 | 12 | 1 | 2 | 4 | 5 | 3 |
| 1000 | 13 | 2 | 3 | 2 | 9 | 5 |
| 10000 | واحد وعشرون | 4 | 3 | 1 | 6 | 3 |
| 100000 | واحد وعشرون | 3 | 2 | 1 | 5 | 6 |
تُظهر المقارنة القوية بين الطريقة 1 والطريقة 2 أن كفاءة عمليات السلسلة أعلى بكثير من عملية عمليات الصفيف ؛ تخبرنا نتائج اختبار الطريقة 6 أن طول الكود لا علاقة له بالأداء. الطريقة 4 لها أفضل أداء شامل (ولكن لماذا ينخفض NUM عندما يكون 100 num غير قابل للحل حقًا) ، والسبب الرئيسي هو:
1. قارن الطرق 1 و 2 ، قم بتشغيل 3 أحرف بدلاً من حرف واحد في كل مرة لتقليل عدد الحلقات ؛
2. طرق المقارنة 3 و 5 و 6 ، دون استخدام تعبيرات منتظمة ، مما يقلل من الاستهلاك.
أخيرًا ، اخترت الطريقة الرابعة كحل التحسين النهائي. يمكن للقراء التعليق إذا كان لديهم أساليب أو اقتراحات تنفيذ أفضل.