چک کردن Palindrome بودن یک رشته در جاوا یکی دیگه از سوالاتی هستش که توی زمان مصاحبه امکان داره از یه دولوپر پرسیده بشه. توی این مطلب قصد داریم یه نگاهی به این مساله بندازیم. اگر پست قبلی در مورد معکوس کردن یک رشته در جاوا رو نخوندید پیشنهاد می کنم یه نگاهی بهش بندازید، چون یه جورایی این دو مطلب به هم مربوط میشن.خب بریم سراغ سوال.
یک رشته رو Palindrome میگیم اگر معکوس یک رشته با خودش برابر باشه. چک کردن Palindrome بودن یک رشته به نظر ساده میاد اما گاهی اوقات مصاحبه کننده از ما چیزایی رو می خواد که شاید باهاش آشنایی نداشته باشیم(مثلا استفاده از Stram Api که در ادامه بهش می رسیم).بیاید بریم سراغ جوابهای این سوال:
۱- روش عادی
توی این روش با استفاده از StringBuilder
و حلقهی For
یک رشتهی معکوس میسازیم و با رشتهی ورودی مقایسش می کنیم:
public boolean normalSolution(String input) {
StringBuilder reverseInput = new StringBuilder();
for (int i = input.toCharArray().length - 1; i >= 0; i--) {
reverseInput.append(input.toCharArray()[i]);
}
return reverseInput.toString().equals(input);
}
۲- روش سریع
اگر پست قبلی رو خونده باشید احتمالا میدونید میخوایم از چه روشی استفاده کنیم. ما می خوایم رشتهی ورودی رو به StringBuilder
بدیم و همزمان با reverse کردنش اون رو با ورودی خودمون مقایسه کنیم:
public boolean fastWay(String input) {
return new StringBuilder(input).reverse().toString().equals(input);
}
۳- استفاده از آرایه
اون بالا فهمیدیم که رشتهی Palindrome با معکوس خودش برابره، خب پس این احتمالا درسته که بگیم اگر این رشته رو به یه آرایه تبدیل کنیم، باید آرایهای داشته باشیم که از کاراکتر ۰ تا وسطش برابر با کاراکتر آخر تا وسطش باشه؟ بزارید تو کد ببینیم تا درکش راحت تر بشه:
public boolean arrayWay(String input) {
int head = 0;
int tail = input.toCharArray().length - 1;
while (head < tail) {
if (input.toCharArray()[head] != input.toCharArray()[tail])
return false;
head++;
tail--;
}
return true;
}
توی کد بالا:
- ما
head
رو به عنوان کاراکتر اول وtail
رو به عنوان کاراکتر آخر قرار دادیم. - از
head
وtail
به سمت هم تا جایی که head از tail کوچیکتر باشه پیش میریم. - اگر کاراکترهایی که که این دوتا با هم مقایسشون می کنن با هم برابر نبودن
false
برمی گردونیم.
۴- تابع بازگشتی
حقیقتش نمیدونم چرا باید بگن که از روش بازگشتی این سوال رو حل کن، اما خب این هم جواب این سوال به روش بازگشتی:
private boolean recursivePalindrome(String text, int head, int tail) {
if (head == tail) {
return true;
}
if ((text.charAt(head)) != (text.charAt(tail))) {
return false;
}
if (head < tail + 1) {
return recursivePalindrome(text, head + 1, tail - 1);
}
return true;
}
۵- استفاده از Java 8 یا Stream API ها
توی جاوا ۸، قابلیت کار با رشتههایی از المانها به این زبان اضافه شد. احتمالا اگر با Rx
ها کار کرده باشید خیلی راحت این api ها رو درک می کنید. پیشنهاد می کنم حتما یه سر به این مطلب بزنید و کاملا با این مفهوم آشنا بشید.
توی این روش میخوایم از یکی از این Stream
ها که برای کار با متغیرهای عددی ساخته شده استفاده کنیم و در واقع استریم رو جایگزین حلقهی For کنیم. بیاید کد رو ببینیم:
public boolean isPalindromeUsingIntStream(String input) {
return IntStream.range(0, input.length() / 2)
.anyMatch(i -> input.charAt(i) == input.charAt(input.length() - i - 1));
}
توی کد بالا:
IntStream
برای کار با Stream های عددی به کار میره وrange
که بعد از اون اومده در واقع مثل حلقهیFor
میگه از ۰ تاinput.length() / 2
رو در نظر بگیر.anyMatch
همونطور که از اسمش پیداست به ما میگه که آیا برای هر کدوم از اعدادی که تو قسمتrange
مشخص شده شرط برقرار هست یا نه.- قسمت داخل پرانتز دقیقا مثل حلقهی
For
هست.
anyMatch
وقتی به ما true بر می گردونه که دو شرط داخل پرانتز برابر باشن. ما توی جاوا دستورnoneMatch
رو هم داریم که دقیقا عکس کد ما عمل میکنه. در واقع ما با قرار دادنnoneMatch
به جایanyMatch
و جایگزین کردن==
با!=
میتونیم همچنان به جواب صحیح دست پیدا کنیم.
public boolean isPalindromeUsingIntStream(String input) {
return IntStream.range(0, input.length() / 2)
.noneMatch(i -> input.charAt(i) != input.charAt(input.length() - i - 1));
}
امیدوارم از این مطلب استفاده کرده باشید. سعی می کنم هر روز یه پست کوتاه از آزمونهای استخدامی دولوپرهایی که برای شرکتهای خارجی اقدام کردن بزارم.