مقدمة
لقد رأيت اليوم سؤالًا جعل الأمر يبدو أنه ليس من الصعب تحديد ما إذا كان الرقم هو رقم رئيسي. لذلك ، قررت تنفيذها.
هيكل دوم
<! doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> حساب الأرقام الأولية في 500 وإخراج </title> <meta name = "viewport" content = "width = device-width ، scale scale = 1.0 ، maximum-scale = 1.0 ، user-scalable = src = "http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"> </script> </head> <body> <viv> <type type = "text" id = "num" value = "" " value = "submit"> </viv> </body> </html> <script> $ (function () {$ ("#submit"). on ('click' ، function () {var num = $ = $ ("#num"). val () ؛ if (isprimenum (num) {ALERT (num+"is") ؛ مركب ") ؛}}) ؛}) ؛ </script>كما هو موضح أعلاه ، نستخدم وظيفة isprimenum (num) لتحديد ما إذا كان رقمًا رئيسيًا. دعونا ننفذ هذه الوظيفة أدناه.
استخدم الحلقة لتحديد ما إذا كان رقمًا رئيسيًا
الدالة isprimenum (num) {for (var i = 2 ؛ i <num ؛ i ++) {if (num ٪ i == 0) {return false ؛}} ؛ return true ؛}المبدأ بسيط نسبيا. من خلال العثور باستمرار على الباقي مع الرقم المستهدف مع 2 أو أكثر ، إذا كنت تستطيع الحصول على 0 ، فهذا يعني أن هذا رقم مركب بدلاً من رقم رئيسي.
ولكن يبدو أن هذا الحساب كبير بعض الشيء
تحسين الطريقة الأولى
الأمر بسيط للغاية ، يتم تنفيذه في فترة قصيرة. ومع ذلك ، يبدو أنه يمكننا تحسينه. ليس علينا مطاردة هذا الرقم والعثور على الباقي. نحتاج فقط إلى حلقة إلى نصف هذا الرقم لحساب ما إذا كان هذا الرقم هو رقم رئيسي.
الدالة isprimenum (num) {for (var i = 2 ؛ i <num/2+1 ؛ i ++) {if (num ٪ i == 0) {return false ؛}} ؛ return true ؛}بعد القياس الفعلي ، تم بالفعل تحسين السرعة بشكل كبير ، لكنني أعلم أن مانتيسا من الرقم حتى 5 أو 5 ، لذلك فهي بالتأكيد ليست رقمًا رئيسيًا ، لذلك ليست هناك حاجة لحسابه. دعنا نحسنه مرة أخرى
لا توجد أرقام حسابية لها حتى 5 أو 5
الدالة isprimenum (num) {if (! isDual (num)) {return false ؛} for (var i = 2 ؛ i <num/2+1 ؛ i ++) {if (num ٪ i == 0) {return false ؛ num.SubString (num.length-1 ، num.length) ؛ return lastNum ٪ 2 == 0 || LastNum ٪ 5 == 0؟ خطأ: صحيح ؛}من خلال هذا التحسين ، يمكننا تقليل مقدار الحساب ونصف الرقم على الأقل. (لكن القياس الفعلي يحسن الأداء ، لأنه يمكن الحكم على هذه الأرقام بسرعة بأنها ليست أرقامًا رئيسية)
هنا ، وجدت وظيفة Sundring () أنه لا يمكن استخدامها على الأرقام ، ولكن لا يمكن استخدامها إلا على الأوتار. للأسف ، لذلك يتم تحويل الرقم إلى سلسلة أولاً.
إذا لم يكن رقمًا أو معالجة عدد صحيح
ما الذي يجب أن أفعله إذا لم تكن مدخلات المستخدم رقمًا أو عشريًا؟ لقد كتبت بسرعة طريقتين لمعالجتها ...
دالة isprimenum (num) {if (! isNum (num)) {return false ؛} if (! isInteger (num)) {return false ؛} if (! isDual (num)) {return false ؛ isInteger (num) {return num == ~~ num؟ صحيح: false ؛} دالة isNum (num) {var num = num.toString () ؛ var lastNum = num.subString (num.length-1 ، num.length) ؛ return lastNum ٪ 2 == 0 || LastNum ٪ 5 == 0؟ خطأ: صحيح ؛}يتم استخدام نصائح هنا ، إحداها هي حول العشرية ~~ num ، والآخر هو تحويل السلاسل إلى الأرقام. +num.
يرجى قراءة منشور مدونتي السابقة "JS التظاهر بمهارات JavaScript Learning (I) بواسطة Fungleo"
هذا لا يحسن أي كفاءة ، ولكنه يلغي فقط إدخال خطأ الحساب. دعونا نفكر في الأمر مرة أخرى ، هل هناك أي طريقة لتحديد ما إذا كان ليس رقمًا رئيسيًا؟
إزالة الأرقام التي يمكن أن تكون قابلة للقسمة على 3 ولا تحسب
الوظيفة isprimenum (num) {if (! isNum (num)) {return false ؛} if (! isInteger (num)) {return false ؛} if (num == 2 || num == 3 || num == 5) {return ؛} if (! isDual (num)) num/5+1 ؛ صحيح: false ؛} وظيفة isNum (num) {return num == +num؟ صحيح: false ؛} الدالة isDual (num) {var num = num.toString () ؛ var lastNum = num.subString (num.length-1 ، num.length) ؛ return lastNum ٪ 2 == 0 || LastNum ٪ 5 == 0؟ false: true ؛} وظيفة isthree (num) {var str = num.toString () ؛ var sum = 0 ؛ for (var i = 0 ؛ i <str.length ؛ i ++) {sum+=+str.substring (i ، i+1) ؛} ؛ return sum ٪ 3 == 0؟ خطأ: صحيح ؛}هنا ، نقوم أولاً بتحويل الرقم إلى سلسلة ، ثم نقسم كل جزء من السلسلة ، وإضافة ومجموعة ، ونستخدم النتيجة و 3 للعثور على المتبقية ، وبعد ذلك يمكننا معرفة ما إذا كان يمكن فصل هذا الرقم بـ 3.
هاها أنا ذكي جدًا ... لم يتحسن أداء الاختبار الفعلي كثيرًا ، لكنه تحسن بالفعل قليلاً. إنه مكتئب قليلاً
ومع ذلك ، إذا استبعدنا الرقم ثلاثي المنافسة ، فلن نحتاج إلى حساب نصفه. ليس لدينا حاجة لحساب نصفه ، نحتاج فقط إلى حساب الثلث. بالإضافة إلى ذلك ، استبعدنا أيضًا 5 ، لذلك نحتاج فقط إلى حساب خمس ...
بعد تعديلات سريعة ، تم تحسين الكفاءة إلى حد كبير !!! أنا قوي ...
ومع ذلك ، وبهذه الطريقة ، سيحدد الكود أنه رقم مركب في 2/3/5. لذلك ، يجب إضافة جملة أخرى.
if (num == 2 || num == 3 || num == 5) {return true ؛}أساليب الآخرين
ثم لم أستطع التفكير في طريقة التحسين ... لذلك بحثت ووجدت الحل التالي. لقد صدمت !!!
وظيفة isPrimenum2 (num) {return!/^.؟ $ |^(..+؟)/1+$/. test (Array (num+1). Join ('1'))}يتم استخدام الطريقة العادية ، إنها قصيرة بالفعل ، لكن يمكنني فهمها حتى لو قرأتها !!!
لا أفهم حقًا ماهية المبدأ ، لذلك أجريت اختبارًا عمليًا ووجدت أن كفاءة الكود الخاصة بي أعلى بكثير من هذا الرمز. من هذا يمكننا أن نرى أن طريقتي لا تزال ممتازة للغاية !!
يستغرق 1600 مللي ثانية لطباعة جميع الأرقام الأولية في 100000 ، ويستغرق هذا الرمز 160000 مللي ثانية. وهذا يعني أن الكود الخاص بي لا يأخذ سوى واحد في المئة من الوقت.
ومع ذلك ، إذا كان بإمكان أي شخص فهم هذا الرمز ، فيرجى توضيحه لي ...
تجديد
بعد قراءة بعض المعلومات ذات الصلة ، يبدو أن الطريقة التي استخدمتها Num/5 أعلاه ليست جيدة جدًا (النتيجة ليست خاطئة). هناك طريقة أفضل ، وهي استخدام Math.SQRT (NUM) للعثور على الجذر التربيعي.
نتائج اختبار الكود الخاصة بي هي كما يلي
كما هو موضح في الشكل أعلاه ، فإن نتيجة الحساب للرمز الخاص بي صحيحة تمامًا. ومع ذلك ، استغرق 1638 ميلي ثانية. لا يزال الأمر كذلك بعد العديد من الاختبارات.
نتائج اختبار طريقة الجذر التربيعي هي كما يلي
كما هو موضح في الشكل أعلاه ، هذه الطريقة هي أكثر علمية وأسرع. يستغرق اختبارات متعددة ، ويستغرق ما بين 1150 ميلي ثانية إلى 1250 ميلي ثانية. مقارنة بأداء الكود الخاص بي ، فهو حوالي 25 ٪.
وأحكم أيضًا على ما إذا كانت الأرقام حتى 5 ، وما إذا كان يمكن تقسيم المبلغ على 3 ، والذي كان وقتًا طويلاً. بالتأكيد آمل أن يقلل من كمية العمليات. لكن هذه الرموز نفسها لديها أيضًا مقدار العمليات. سأقوم بإزالة كل الكود الخاص بي ثم انظر إليه.
تم تحسين الأداء مرة أخرى. يبدو أن جميع حساباتي محسنة سلبا!
أخيرًا ، الرمز كما يلي:
وظيفة isprimenum (num) {if (! isNum (num)) {return false ؛} if (! isInteger (num)) {return false ؛} for (var i = 2 ؛ i <= math.sqrt (num) ؛ i ++) {if (num ٪ i == 0) {return false ؛} ؛ صحيح: false ؛} وظيفة isNum (num) {return num == +num؟ صحيح: خطأ ؛}ملخص: كان ذلك تمامًا بسبب الحساب السيئ الذي دفعني إلى أن أكون ذكيًا في المقدمة. ومع ذلك ، فإن ممارسة التقنيات الصغيرة جيدة أيضًا -_- |||
أخيرًا ، دعونا نلقي نظرة على المدة التي يستغرقها حساب جميع الأرقام الرئيسية في غضون مليون
ما سبق هو ملخص لأساليب الحكم على ما إذا كان الرقم هو رقم رئيسي قدمه المحرر. آمل أن يكون ذلك مفيدًا للجميع.