CodeGym /مدونة جافا /Random-AR /برنامج جافا للمضروب
John Squirrels
مستوى
San Francisco

برنامج جافا للمضروب

نشرت في المجموعة
سنتحدث اليوم عن المضروب والطرق الأكثر شيوعًا للعثور على المضروب. هذه إحدى الوظائف الأساسية التي يحتاج المبرمج إلى معرفتها والقدرة على التعامل معها. حسنا، دعونا نبدأ. مضروب الرقم n، المشار إليه بـ n!، هو قيمة منتج (ضرب) جميع الأعداد الطبيعية من 1 إلى n. إليك ما يبدو عليه (دعنا نقوم بتحديث معرفتك بالرياضيات):
1! = 1 2! = 1 * 2 = 2 3! = 1 * 2 * 3 = 6 4! = 1*2*3*4 = 24 5! = 1*2*3*4*5 = 120
وهناك قاعدة صغيرة أخرى للرقم 0:
!0 = 1
إذا أردنا حساب الفرق بين 6! و 4!:
6!-4! = 1⋅2⋅3⋅4⋅5⋅6 - 1⋅2⋅3⋅4 = 720 - 24 = 696
دعونا نرى كيف سيبدو هذا عند تنفيذه في البرمجة. سوف نستكشف بعض الطرق لكيفية القيام بحسابات المضروب في جافا.

الحل العادي في برنامج مضروب

إليك برنامج عاملي بسيط باستخدام الحلقة:
class FactorialExample{
 public static void main(String args[]){
  int i,fact=1;
  int number=7;// our number to do the necessary calculations in class Factorial
  for(i=1;i<=number;i++){
      fact=fact*i;
  }
  System.out.println("Factorial of "+number+" is: "+fact);
 }
}
سيكون مخرجنا على وحدة التحكم هو:
مضروب العدد 7 هو: 5040
ومثال آخر لفرز الأمور:
public static int getFactorial(int f) {
  int result = 1;
  for (int i = 1; i <= f; i++) {
     result = result * i; // finding factorial of number using loops
  }
  return result;
}
لا يوجد شيء صعب هنا: نستخدم الرقم الذي تم تمريره كحجم للحلقة التي نضرب فيها جميع الأرقام السابقة حتى نصل إلى f. وفي الرئيسي:
System.out.println(getFactorial(6) - getFactorial(4));
باختبار الكود نرى أننا حصلنا على النتيجة المرجوة: 696.

الحل العودي

يحدث العودية عندما تستدعي الطريقة نفسها. تسمى هذه الطريقة بالطريقة العودية. كقاعدة عامة، يتكون من جزأين:
  1. شرط الإنهاء - عندما يتم استيفاء شرط الإنهاء، يجب أن تتوقف الطريقة عن استدعاء نفسها وتبدأ في تمرير القيم لأعلى. بعد كل شيء، إذا لم يكن هناك شرط إنهاء، فسيكون لدينا حلقة لا نهائية، حيث تستدعي الطريقة نفسها بشكل متكرر حتى نحصل على StackOverflowError .
  2. مهما كان المنطق الذي يتطلبه الموقف، بالإضافة إلى استدعاء متكرر، ولكن بقيمة إدخال مختلفة.
يعد العثور على العامل المضروب في Java مثالًا رائعًا لوقت استخدام التكرار:
public static int getFactorial(int f) { // finding factorial of number using recursive solution
  if (f <= 1) {
     return 1;
  }
  else {
     return f * getFactorial(f - 1);
  }
}
ستكون حالة إنهاء العودية لدينا عندما نصل إلى 1. إذا لم تكن المعلمة 1، فإننا نضرب القيمة الحالية نتيجة الاستدعاء العودي التالي للطريقة (التي نمرر إليها القيمة الحالية ناقص 1).

الحل مع تيار

أي شخص ليس على دراية بوظيفة Stream في Java، أو أي شخص يريد تحديث ذاكرته، سيستفيد من القراءة هنا .
public static int getFactorial(int f) { // finding factorial of number using Stream
  if (f <= 1) {
     return 1;
  }
  else {
     return IntStream.rangeClosed(2, f).reduce((x, y) -> x * y).getAsInt();
  }
}
نستخدم هنا فئة IntStream الخاصة ، والتي تمنحنا إمكانات إضافية عند العمل مع دفق من قيم int. لإنشاء مثل هذا التدفق، نستخدم طريقة rangeClosed الثابتة الخاصة به، والتي تولد قيمًا من 2 إلى f، شاملة، بزيادات قدرها 1. بعد ذلك، نستخدم طريقة الاختزال لدمج كل القيم. وبشكل أكثر تحديدًا، نوضح كيف نريد دمج القيم. وأخيرًا، نحصل على القيمة الناتجة باستخدام طريقة getAsInt الطرفية .

باستخدام BigInteger

في Java، غالبًا ما يتم استخدام فئة BigInteger للتعامل مع الأرقام، وخاصة الأرقام الكبيرة. في الواقع، إذا استخدمنا int ، فإن الحد الأقصى للمضروب الذي يمكننا التعامل معه دون فقدان البيانات هو 31. بالنسبة لنوع البيانات الطويلة ، الحد الأقصى للمضروب هو 39. ولكن ماذا لو كنا بحاجة إلى المضروب 100؟ دعونا نكيف الحلول السابقة مع BigInteger.برنامج جافا للمضروب - 2

الحل العادي

public static BigInteger getFactorial(int f) { // finding factorial of number using BigInteger
  BigInteger result = BigInteger.ONE;
  for (int i = 1; i <= f; i++)
     result = result.multiply(BigInteger.valueOf(i));
  return result;
}
الخوارزمية هي نفسها بشكل أساسي، لكننا هنا نستخدم إمكانيات BigInteger: BigInteger.ONE هي قيمة البداية 1، ويتم استخدام multiply() لضرب قيمة العامل السابقة والرقم الحالي.

الحل العودي

public static BigInteger getFactorial(int f) {
  if (f <= 1) {
     return BigInteger.valueOf(1);
  }
  else {
     return BigInteger.valueOf(f).multiply(getFactorial(f - 1));
  }
}
لا يتغير المنطق العام للحل، باستثناء إضافة بعض الطرق للعمل مع BigInteger.

الحل مع تيار

public static BigInteger getFactorial(int f) {
  if (f < 2) {
     return BigInteger.valueOf(1);
  }
  else {
     return IntStream.rangeClosed(2, f).mapToObj(BigInteger::valueOf).reduce(BigInteger::multiply).get();
  }
}
كل شيء هو نفسه في الأساس، ولكن مع BigInteger. تمنحنا فئة Stream طريقة MapToObj ، التي نستخدمها لتحويل قيم int إلى BigInteger من أجل ضربها مع نفسها باستخدام طريقة الضرب (وتمت إضافة get() للحصول على كائن من الغلاف الاختياري ). إذا قمنا بتشغيل أي من هذه الطرق الثلاث بوسيطة 100، فسوف نتجنب تجاوز سعة المكدس ونحصل على النتيجة الصحيحة:
9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825 11852109168640000000000000000
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION