یہ سمجھنے کے لیے کہ تکرار کیا ہے، آپ کو یہ سمجھنا ہوگا کہ تکرار کیا ہے۔ درحقیقت، اس طرح کے افعال کو سمجھنے میں کوئی مشکل نہیں ہے؛ آپ کو صرف ایک بار اسے اچھی طرح سمجھنا ہوگا۔ اور جب پروگرامنگ کی بات آتی ہے تو مشق کریں۔
تکرار نہ صرف پروگرامنگ میں ہوتی ہے بلکہ حقیقی زندگی میں بھی ہوتی ہے۔ اپنے ہاتھوں میں ایک آئینہ لیں اور دوسرے آئینے کے سامنے کھڑے ہوں۔ انعکاس کا انعکاس انعکاس میں ہوگا وغیرہ وغیرہ۔ آپ لامحدود مظاہر کو لامحدودیت میں جاتے ہوئے دیکھیں گے۔ آپ مضمون میں "حقیقی" تکرار کے بارے میں مزید معلومات حاصل کر سکتے ہیں " گراؤنڈ ہاگ ڈے کے لیے وقف... " آئیے حقیقی دنیا سے ایک پروگرامر کی روزمرہ کی زندگی کی طرف لوٹتے ہیں۔ سادہ تعریف: جاوا میں تکراری فنکشنز وہ فنکشن ہیں جو خود کو کہتے ہیں۔ میں آپ کو ایک بہت سادہ اور بہت مؤثر مثال دیتا ہوں:
ایک طریقہ کا دوسرے پر کیا فائدہ؟ ایسا نہیں لگتا کہ کوئی بڑا فرق ہے، لیکن درحقیقت، بہت ساری تکراری کالوں کا کارکردگی اور میموری کی کھپت پر منفی اثر پڑے گا: کال اسٹیک تقریباً بے قابو وسیلہ ہے اور ایک ہی ریکسریو فنکشن کو کال کرنے کے لیے مختلف حالات میں، ہمیں اس وسیلہ سے وابستہ مسائل درپیش ہو سکتے ہیں یا نہیں۔ تکرار کے استعمال سے حل ہونے والے تقریباً تمام مسائل (سائیکل جیسے
public void recursionFucn() {
System.out.println("Привет, JavaRush!");
recursionFucn();
}
یہ نقصان دہ کیوں ہے؟ میرا مشورہ ہے کہ آپ اسے خود چیک کریں! اگر آپ یہ مہم جوئی کرنے کا فیصلہ کرتے ہیں (اور آپ کا امکان ہے کہ آپ پروگرامر کریں گے!)، تبصرے میں لکھیں کہ JVM کیا غلطی کرے گا =) یہ مثال، اور بہت سی دوسری، یہ ظاہر کرتی ہے کہ جاوا میں تکرار کے استعمال کے ساتھ رابطہ کیا جانا چاہیے۔ احتیاط. آپ کو یہ سمجھنے کی ضرورت ہے کہ مسئلہ کو حل کرنے کے لیے اس طرح کا نقطہ نظر کہاں، کب اور کیوں جائز ہے، اور اس بات کو یقینی بنائیں کہ آپ کا فنکشن پروگرام کے نفاذ کو "گراؤنڈ ہاگ ڈے" میں تبدیل نہ کرے۔ تکرار کو سمجھنے کے لیے دو اور اہم تعریفیں ہیں:
- تکرار کی بنیاد - تکراری کالوں کے بلاک سے باہر نکلنے کی شرط - مسئلہ کا بنیادی حل، ایسی شرائط کے تحت جب تکرار کال کرنے کی ضرورت نہ ہو۔
- تکرار مرحلہ وہ ہوتا ہے جب پیرامیٹرز کو تبدیل کرتے وقت کوئی فنکشن خود کو کال کرتا ہے۔
N
(N کے طور پر ظاہر کیا جاتا ہے!) سے اعداد کی پیداوار ہے 1 до N: N! = 1 * 2 * 3 * … (N - 1) * N
۔ ویسے، تعریف کے لحاظ سے صفر کا فیکٹوریل 1 کے برابر ہے۔ لہٰذا فیکٹوریل کسی بھی مثبت عدد اور صفر کے لیے پایا جا سکتا ہے (ریاضی کی زبان میں - غیر منفی عدد کے سیٹ کے لیے یا قدرتی اعداد کے سیٹ کے لیے اور صفر)۔ مجھے لگتا ہے کہ آپ سمجھتے ہیں کہ آپ لوپس کا استعمال کرتے ہوئے فیکٹریل پروگرام کر سکتے ہیں۔ دراصل، اس مسئلے کو حل کرنے کے لیے یہاں ایک غیر تکراری طریقہ ہے:
private int fact(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
آئیے ایک چیک شامل کریں کہ نمبر مثبت ہے اور ایک عدد، اور صفر کے لیے الگ چیک۔
private int fact(int n) {
if (n < 0) {
System.out.println("Зачем тебе факториал из отрицательного числа?");
return null;
}
int result = 1;
if (n == 0) {
return result;
}
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
اب میں اس مسئلے کو بار بار حل کرنے کے لیے طریقہ کار کوڈ دوں گا۔
private int factorial(int n) {
int result = 1;
if (n == 1 || n == 0) {
return result;
}
result = n * factorial(n-1);
return result;
}
آئیے کالوں کے آؤٹ پٹ کے نتائج کو دیکھتے ہیں:
System.out.println(factorial(0));
System.out.println(factorial(1));
System.out.println(factorial(2));
System.out.println(factorial(3));
System.out.println(factorial(4));
System.out.println(factorial(5));
System.out.println(factorial(6));
ہمیں متوقع قدریں ملتی ہیں:
1
1
2
6
24
120
720
آئیے ایک اچھا آؤٹ پٹ شامل کریں اور بڑی تعداد کے لیے فیکٹریل کا حساب لگائیں:
private int factorial(int n) {
int result = 1;
if (n == 0) {
System.out.print(" = ");
return result;
}
if (n == 1) {
System.out.print(" * 1 = ");
return result;
}
System.out.print(n);
if (n != 2) {
System.out.print(" * ");
}
result = n * factorial(n-1);
return result;
}
System.out.println(factorial(15) + "!");
ہم حاصل کرتے ہیں: 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 1 307 674 368 000!
اس صورت میں، تکراری فنکشن کا استعمال جائز اور محفوظ ہے۔ ہم نے تکراری بلاک سے باہر نکلنے کی شرط کو واضح طور پر بیان کیا ہے، اور ہمیں یقین ہے کہ یہ قابل حصول ہے: ہم ایک غیر منفی عدد عدد داخل کرتے ہیں، اگر نمبر صفر یا ایک کے برابر ہے، تو ہم نتیجہ واپس کرتے ہیں، اگر نمبر زیادہ ہے۔ ہم نتیجہ کو عدد کے فنکشن سے ضرب دیتے ہیں n-1
۔ تین کے فیکٹوریل کو بطور مثال استعمال کرنا:
factorial(3) внутри себя выполнит следующее:
result = 3 * factorial(2); (рекурсивный вызов)
factorial(2) внутри себя выполнит следующее:
result = 2 * factorial(1); (рекурсивный вызов)
factorial(1) вернет 1 (базис рекурсии)
factorial(2) вернет 2 * 1
factorial(3) вернет 3 * 2 * 1
استعمال میں احتیاط کے بارے میں: اس فنکشن کی کمزوری کیا ہے؟ اگر آپ کسی طریقہ کو پیرامیٹر کے طور پر منفی نمبر دیتے ہیں، تو چیک کریں۔
if (n == 1 || n == 0) {
return result;
}
کوئی معنی نہیں رکھتا اور ہم خود کو کال کرنے کے نہ ختم ہونے والے چکر میں ختم ہو جائیں گے۔ یہ غیر منفی کے لئے ایک چیک شامل کرنے کے قابل ہے:
if (n < 0) {
System.out.println(«Зачем тебе факториал отрицательного числа?»);
return null;
}
اور سب ٹھیک ہو جائے گا۔
for-each
) کو بھی بار بار حل کیا جا سکتا ہے۔ تکرار کا فائدہ پڑھنے کی اہلیت اور لکھنے میں آسانی ہے، ہم نے اوپر کے نقصانات کے بارے میں بات کی ہے: "اپنے آپ کو پاؤں میں گولی مارنے" کا موقع خیالی نہیں ہے۔ نام نہاد "پیچیدہ تکرار" کا استعمال کرتے وقت آپ کو مزید محتاط رہنے کی ضرورت ہے: ایک فنکشن A()
ایک فنکشن کو کال کرے گا B()
جو فنکشن کو کال کرتا ہے A()
۔ اس طرح کے کام کی ایک مثال: کی قدر کا حساب لگانا x^n/(n!)
۔ فیکٹوریل، جیسا کہ ہم نے اوپر بات کی ہے، غیر منفی عدد کے سیٹ پر بیان کی گئی ہے۔ آخر میں، میں حل کوڈ دوں گا۔ پیچیدہ تکرار دو طریقوں پر مشتمل ہوگی:
private double calculate(int x, int n) {
return power(x, n) / n;
}
private double power(int x, int n) {
if (n == 1) return x;
return x * calculate(x, n - 1);
}
تکرار داخل کرنے کے لیے، ایک طریقہ استعمال کیا جاتا ہے calculate
، جو ایک طریقہ کہتا ہے power
، جو بدلے میں ایک طریقہ کہتا ہے calculate
۔ ہم نے طاقت کے طریقہ کار میں تکرار کی بنیاد کی وضاحت کی:
if (n == 1) return x;
تکرار کے مرحلے کی بھی وہاں تعریف کی گئی ہے:
return x * calculate(x, n - 1);
ان پٹ ڈیٹا کی درستگی کے لیے ایک چیک شامل کرنا باقی ہے:
- صفر کے علاوہ کوئی بھی عدد صفر کی طاقت کے برابر ہے
1
۔n = 0
پھر اگرn! = 1
. اسے واپس کرنے کی ضرورت ہے1
۔ - کسی بھی طاقت کا صفر صفر کے برابر ہے۔
- ہم قسم کی غیر یقینی صورتحال پر غور نہیں کریں گے
0^0
اور ایسے ان پٹ ڈیٹا کو غلط کے طور پر قبول کریں گے۔
private double calculate(int x, int n) throws ArithmeticException {
if (x == 0 && n == 0) {
throw new ArithmeticException("Невалидные входные данные: Неопределенность типа 0^0");
}
if (n < 0) {
throw new ArithmeticException("Невалидные входные данные: Факториал из отрицательного числа!");
}
if (n == 0) {
return 1;
}
if (x == 0) {
return 0;
}
if (x == 0) {
return 0;
}
return power(x, n) / n;
}
private double power(int x, int n) {
if (n == 1) return x;
return x * calculate(x, n - 1);
}
ٹھیک ہے، کسی فنکشن کو کال کرتے وقت آپ کو غلطی کو پکڑنے کے لیے یاد رکھنا ہوگا:
try {
System.out.println(calculate(x, n));
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
GO TO FULL VERSION