Создание рекурсивного метода для палиндрома

Я пытаюсь создать программу Palindrome, используя рекурсию в Java, но я застрял, это то, что у меня есть до сих пор:

 public static void main (String[] args){
 System.out.println(isPalindrome("noon"));
 System.out.println(isPalindrome("Madam I'm Adam"));
 System.out.println(isPalindrome("A man, a plan, a canal, Panama"));
 System.out.println(isPalindrome("A Toyota"));
 System.out.println(isPalindrome("Not a Palindrome"));
 System.out.println(isPalindrome("asdfghfdsa"));
}

public static boolean isPalindrome(String in){
 if(in.equals(" ") || in.length() == 1 ) return true;
 in= in.toUpperCase();
 if(Character.isLetter(in.charAt(0))
}

public static boolean isPalindromeHelper(String in){
 if(in.equals("") || in.length()==1){
  return true;
  }
 }
}

Кто-нибудь может предложить решение моей проблемы?


person Nightshifterx    schedule 06.12.2010    source источник
comment
Эээ... отступ 1 пробел. Это как не отступ вообще. Лучше использовать 2, 4 или 8 пробелов (или табуляции) для отступа. О, и, пожалуйста, используйте кнопку кода формата в следующий раз, чтобы он отображался правильно.   -  person ThiefMaster    schedule 06.12.2010
comment
И где здесь рекурсия?   -  person Roman    schedule 06.12.2010
comment
Много дубликатов или почти дубликатов из SO-поиска палиндрома: stackoverflow.com/search?q=palindrome   -  person The Archetypal Paul    schedule 06.12.2010
comment
Сначала вставьте свой код, затем выберите его и нажмите кнопку Пример кода.   -  person Peter Lang    schedule 06.12.2010
comment
Разве in.length() == 1 не покрывает также и in.equals(" ")?   -  person Svish    schedule 11.10.2012


Ответы (18)


Здесь я вставляю код для вас:

Но я настоятельно рекомендую вам знать, как это работает,

судя по вашему вопросу, вы совершенно нечитабельны.

Попробуйте понять этот код. Читать комментарии из кода

import java.util.Scanner;
public class Palindromes
{

    public static boolean isPal(String s)
    {
        if(s.length() == 0 || s.length() == 1)
            // if length =0 OR 1 then it is
            return true; 
        if(s.charAt(0) == s.charAt(s.length()-1))
            // check for first and last char of String:
            // if they are same then do the same thing for a substring
            // with first and last char removed. and carry on this
            // until you string completes or condition fails
            return isPal(s.substring(1, s.length()-1));

        // if its not the case than string is not.
        return false;
    }

    public static void main(String[]args)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("type a word to check if its a palindrome or not");
        String x = sc.nextLine();
        if(isPal(x))
            System.out.println(x + " is a palindrome");
        else
            System.out.println(x + " is not a palindrome");
    }
}
person jmj    schedule 06.12.2010
comment
Ничего себе, это буквально первый раз, когда я использовал этот веб-сайт, и я действительно получаю быстрые ответы. Всем спасибо. - person Nightshifterx; 06.12.2010
comment
@Nightshifterx, если вы используете его впервые, я бы посоветовал вам принять концепцию ответа, вы должны принять ответ, который вы считаете наиболее полезным - person jmj; 06.12.2010
comment
org, я внедрил ваш логический метод в свой код, отредактировал его и запустил, однако только полдень вернулся как истинный палиндром, но разве мадам, я Адам, или asdfghfdsa также не вернут true? они оба вернули ложь. - person Nightshifterx; 06.12.2010
comment
@Nightshifterx Потому что они оба не палиндром - person jmj; 06.12.2010
comment
Аааа ладно я только что перечитал определение настоящего палиндрома спасибо за помощь. Как мне реализовать концепцию принятия ответа, о которой вы говорите? - person Nightshifterx; 06.12.2010
comment
@Nightshifterx, посмотри на мой ответ по делу мадам, я Адам. - person aioobe; 06.12.2010
comment
asdfghfdsa ни в каком смысле не является палиндромом (один g, один h). и, похоже, кепки - это большая проблема с мадам, я Адам - person jon_darkstar; 06.12.2010
comment
@jon_darstar, и пробелы, и символ ' :-) - person aioobe; 06.12.2010
comment
@aioobe, по-вашему, вторая строка - это палиндром, не так ли? - person jmj; 06.12.2010
comment
Это "asdfghfdsa"? Нет, так как у него gh посередине. - person aioobe; 06.12.2010
comment
@aioobe, нет, извините, я не спрашиваю madam I'm Adam - person jmj; 06.12.2010
comment
@org.life.java, см. мой метод isPalindromeForgiving :-) - person aioobe; 06.12.2010
comment
@aioobe, ты, кажется, удаляешь пробелы и игнорируешь регистр, я впервые слышу это прощающее :) - person jmj; 06.12.2010
comment
@Nightshifterx, щелкнув правый знак newar, чтобы ответить, который вы можете принять, ПРИМЕЧАНИЕ: вы должны выбрать наиболее полезный ответ. - person jmj; 06.12.2010
comment
@JigarJoshi, ваш код тяжелый. Мы не хотим создавать строковые новые объекты подстроки для каждого рекурсивного вызова. Мы можем просто передавать индексы и работать с одной и той же ссылкой на интернированную строку. - person Ace; 22.07.2016

Что ж:

  • Непонятно, почему у вас два метода с одинаковой сигнатурой. Для чего они предназначены?
  • В первом методе, почему вы тестируете для тестирования одного пробела или любого отдельного символа?
  • Возможно, вы захотите обобщить условие завершения до «если длина меньше двух».
  • Consider how you want to recurse. One option:
    • Check that the first letter is equal to the last letter. If not, return false
    • Теперь возьмите подстроку, чтобы эффективно удалить первую и последнюю буквы, и рекурсивно
  • Это должно быть упражнением в рекурсии? Это, безусловно, один способ сделать это, но далеко не единственный.

На данный момент я не собираюсь излагать это более четко, потому что я подозреваю, что это домашнее задание - действительно, некоторые могут счесть приведенную выше помощь слишком большой (сам я, конечно, немного колеблюсь). Если у вас есть какие-либо проблемы с приведенными выше советами, обновите свой вопрос, чтобы показать, как далеко вы продвинулись.

person Jon Skeet    schedule 06.12.2010
comment
Хорошо, спасибо, во-первых, чтобы прояснить ситуацию, как работает реализация формата кода? Я нажимаю кнопку кода, и он говорит - person Nightshifterx; 06.12.2010
comment
введите код здесь, я скопирую туда свой код, и будет закодирована только первая строка. - person Nightshifterx; 06.12.2010
comment
К сожалению, я пропустил то, что вы сказали, это не домашнее задание, это на самом деле прошлый лабораторный из моего класса Java в колледже, не всегда достаточно времени, чтобы закончить его, теперь я немного отстал и сижу в библиотеке, пытаясь сделать это. - person Nightshifterx; 06.12.2010
comment
@Nightshifterx: Для меня это звучит как домашнее задание :) Что касается форматирования кода, вставьте код, затем выберите его и нажмите кнопку (или Ctrl-K). - person Jon Skeet; 06.12.2010
comment
@Nightshifterx: альтернатива форматированию кода: просто сделайте отступ в каждой строке кода на дополнительные 4 пробела (что делает Ctrl-K) - person user85421; 07.12.2010

public static boolean isPalindrome(String in){
   if(in.equals(" ") || in.length() < 2 ) return true;
   if(in.charAt(0).equalsIgnoreCase(in.charAt(in.length-1))
      return isPalindrome(in.substring(1,in.length-2));
   else
      return false;
 }

Может быть, вам нужно что-то вроде этого. Не тестировалось, я не уверен насчет строковых индексов, но это отправная точка.

person mauretto    schedule 06.12.2010
comment
Зачем вам in.equals(" ")? (В этом случае длина в любом случае равна < 2.) - person aioobe; 06.12.2010
comment
Я оставил функцию in.equals(), потому что это была его аргументация (см. рассматриваемый код). Эффективно бесполезно, но он спросил об использовании рекурсивного метода. - person mauretto; 07.12.2010
comment
У вас в рекурсивной функции -2, у другого плаката -1. Как лучше? Лично я продолжаю получать правду с этим кодом, не знаю почему. - person Azurespot; 18.08.2017

Я думаю, что рекурсия - не лучший способ решить эту проблему, но один рекурсивный способ, который я вижу здесь, показан ниже:

String str = prepareString(originalString); //make upper case, remove some characters 
isPalindrome(str);

public boolean isPalindrome(String str) {
   return str.length() == 1 || isPalindrome(str, 0);
}

private boolean isPalindrome(String str, int i) {
       if (i > str.length / 2) {
      return true;
   }
   if (!str.charAt(i).equals(str.charAt(str.length() - 1 - i))) {
      return false;
   }
   return isPalindrome(str, i+1);
}
person Roman    schedule 06.12.2010

Вот что я делаю:

public class Test {

    public static boolean isPalindrome(String s) {
        return s.length() <= 1 ||
            (s.charAt(0) == s.charAt(s.length() - 1) &&
             isPalindrome(s.substring(1, s.length() - 1)));
    }


    public static boolean isPalindromeForgiving(String s) {
        return isPalindrome(s.toLowerCase().replaceAll("[\\s\\pP]", ""));
    }


    public static void main(String[] args) {

        // True (odd length)
        System.out.println(isPalindrome("asdfghgfdsa"));

        // True (even length)
        System.out.println(isPalindrome("asdfggfdsa"));

        // False
        System.out.println(isPalindrome("not palindrome"));

        // True (but very forgiving :)
        System.out.println(isPalindromeForgiving("madam I'm Adam"));
    }
}
person aioobe    schedule 06.12.2010

Некоторые коды являются тяжелыми для строк. Вместо создания подстроки, которая создает новый объект, мы можем просто передавать индексы в рекурсивных вызовах, как показано ниже:

private static boolean isPalindrome(String str, int left, int right) {
    if(left >= right) {
        return true;
    }
    else {
        if(str.charAt(left) == str.charAt(right)) {

            return isPalindrome(str, ++left, --right);
        }
        else {
            return false;
        }
    }
}


 public static void main(String []args){
    String str = "abcdcbb"; 
    System.out.println(isPalindrome(str, 0, str.length()-1));
 }
person Ace    schedule 22.07.2016

Вот три простых реализации, первая — oneliner:

public static boolean oneLinerPalin(String str){
    return str.equals(new StringBuffer(str).reverse().toString());
}

Это, конечно, довольно медленно, так как он создает строковый буфер и переворачивает его, и вся строка всегда проверяется независимо от того, является ли она палиндромом или нет, поэтому вот реализация, которая проверяет только необходимое количество символов и делает это на месте, поэтому без дополнительных строковых буферов:

public static boolean isPalindrome(String str){

    if(str.isEmpty()) return true;

    int last = str.length() - 1;        

    for(int i = 0; i <= last / 2;i++)
        if(str.charAt(i) != str.charAt(last - i))
            return false;

    return true;
}

И рекурсивно:

public static boolean recursivePalin(String str){
    return check(str, 0, str.length() - 1);
}

private static boolean check (String str,int start,int stop){
    return stop - start < 2 ||
           str.charAt(start) == str.charAt(stop) &&
           check(str, start + 1, stop - 1);
}
person HaskellElephant    schedule 06.12.2010

Попробуй это:

package javaapplicationtest;

public class Main {

    public static void main(String[] args) {

        String source = "mango";
        boolean isPalindrome = true;

        //looping through the string and checking char by char from reverse
        for(int loop = 0; loop < source.length(); loop++){          
            if( source.charAt(loop) != source.charAt(source.length()-loop-1)){
                isPalindrome = false;
                break;
            }
        }

         if(isPalindrome == false){
             System.out.println("Not a palindrome");
         }
         else
             System.out.println("Pailndrome");

    }

}
person Naresh    schedule 20.07.2012

Вот рекурсивный метод, который будет игнорировать указанные символы:

public static boolean isPal(String rest, String ignore) {
    int rLen = rest.length();
    if (rLen < 2)
        return true;
    char first = rest.charAt(0)
    char last = rest.charAt(rLen-1);
    boolean skip = ignore.indexOf(first) != -1 || ignore.indexOf(last) != -1;
    return skip || first == last && isPal(rest.substring(1, rLen-1), ignore);
}

Используйте это так:

isPal("Madam I'm Adam".toLowerCase(), " ,'");
isPal("A man, a plan, a canal, Panama".toLowerCase(), " ,'");

Нет смысла включать нечувствительность к регистру в рекурсивный метод, поскольку это нужно сделать только один раз, если только вам не разрешено использовать метод .toLowerCase().

person dansalmo    schedule 14.12.2013

нет кода меньше этого:

public static boolean palindrome(String x){
    return (x.charAt(0) == x.charAt(x.length()-1)) && 
        (x.length()<4 || palindrome(x.substring(1, x.length()-1)));
}

если вы хотите что-то проверить:

public static boolean palindrome(String x){
    if(x==null || x.length()==0){
        throw new IllegalArgumentException("Not a valid string.");
    }
    return (x.charAt(0) == x.charAt(x.length()-1)) && 
        (x.length()<4 || palindrome(x.substring(1, x.length()-1)));
}

ЛОЛ Б-]

person Devil_Dj    schedule 14.12.2013

public static boolean isPalindrome(String p)
    {
        if(p.length() == 0 || p.length() == 1)
            // if length =0 OR 1 then it is
            return true; 

         if(p.substring(0,1).equalsIgnoreCase(p.substring(p.length()-1))) 
            return isPalindrome(p.substring(1, p.length()-1));


        return false;
    }

Это решение не чувствительно к регистру. Следовательно, например, если у вас есть следующее слово: «адинида», то вы получите истину, если сделаете «аднинида», или «аднинида», или «адинидА», что нам и нужно.

Мне нравится ответ @JigarJoshi, но единственная проблема с его подходом заключается в том, что он даст вам ложь для слов, содержащих заглавные буквы.

person bangbang    schedule 22.02.2015

Пример палиндрома:

static boolean isPalindrome(String sentence) {

    /*If the length of the string is 0 or 1(no more string to check), 
     *return true, as the base case. Then compare to see if the first 
     *and last letters are equal, by cutting off the first and last 
     *letters each time the function is recursively called.*/

    int length = sentence.length();

    if (length >= 1)
        return true;
    else {
        char first = Character.toLowerCase(sentence.charAt(0));
        char last = Character.toLowerCase(sentence.charAt(length-1));

        if (Character.isLetter(first) && Character.isLetter(last)) {
            if (first == last) {
                String shorter = sentence.substring(1, length-1);
                return isPalindrome(shorter);
            } else {
                return false;
            }
        } else if (!Character.isLetter(last)) {
            String shorter = sentence.substring(0, length-1);
            return isPalindrome(shorter);
        } else {
            String shorter = sentence.substring(1);
            return isPalindrome(shorter);
        }
    }
}

Звонил:

System.out.println(r.isPalindrome("Madam, I'm Adam"));

Напечатает true, если палиндром, если нет, напечатает false.

Если длина строки равна 0 или 1 (строка больше не проверяется), верните true в качестве базового случая. На этот базовый случай будет ссылаться вызов функции прямо перед этим. Затем сравните, чтобы увидеть, равны ли первая и последняя буквы, отрезав первую и последнюю буквы каждый раз, когда функция рекурсивно вызывается.

person David Rifkin    schedule 29.11.2016
comment
Это будет работать только для палиндромов без регистра и специальных символов, что, судя по вопросу, и есть то, что он ищет. - person mascoj; 30.11.2016
comment
Это обновленный палиндром, теперь учитывающий регистр и специальные символы @mascoj. - person David Rifkin; 02.12.2016
comment
@mascoj ты это проверял? - person David Rifkin; 05.12.2016

Вот код для проверки палиндрома без создания множества строк

public static boolean isPalindrome(String str){
    return isPalindrome(str,0,str.length()-1);
}

public static boolean isPalindrome(String str, int start, int end){
    if(start >= end)
        return true;
    else
        return (str.charAt(start) == str.charAt(end)) && isPalindrome(str, start+1, end-1);
}
person Dheeraj Kumar Gopali    schedule 24.03.2017

открытый класс PlaindromeNumbers {

int func1(int n)
{
    if(n==1)
        return 1;

    return n*func1(n-1);
}

static boolean check=false;
int func(int no)
{

    String a=""+no;

    String reverse = new StringBuffer(a).reverse().toString();

    if(a.equals(reverse))
    {

        if(!a.contains("0"))
        {
           System.out.println("hey");
            check=true;
            return Integer.parseInt(a);
        }

    }

      //  else
      //  {
    func(no++);
    if(check==true)
    {
        return 0;
    }
       return 0;   
   }
public static void main(String[] args) {
    // TODO code application logic here
    Scanner in=new Scanner(System.in);
    System.out.println("Enter testcase");
   int testcase=in.nextInt(); 
   while(testcase>0)
   {
     int a=in.nextInt();
     PlaindromeNumbers obj=new PlaindromeNumbers();
       System.out.println(obj.func(a));
       testcase--;
   }
}

}

person taha rafi    schedule 07.07.2017

Простое решение 2. Сценарий – (строка четной или нечетной длины)

Базовое условие и рекурсивный алгоритм (ch, i, j)

  1. i==j //четная длина

  2. если i‹ j рекурсивный вызов (ch, i +1,j-1)

  3. иначе вернуть ch[i] ==ch[j]// Дополнительное базовое условие для старой длины

public class HelloWorld {


 static boolean ispalindrome(char ch[], int i, int j) {
  if (i == j) return true;

  if (i < j) {
   if (ch[i] != ch[j])
    return false;
   else
    return ispalindrome(ch, i + 1, j - 1);
  }
  if (ch[i] != ch[j])
   return false;
  else
   return true;

 }
 public static void main(String[] args) {
  System.out.println(ispalindrome("jatin".toCharArray(), 0, 4));
  System.out.println(ispalindrome("nitin".toCharArray(), 0, 4));
  System.out.println(ispalindrome("jatinn".toCharArray(), 0, 5));
  System.out.println(ispalindrome("nittin".toCharArray(), 0, 5));

 }
}
person jatin Goyal    schedule 17.03.2018

для этого вам нужно не только знать, как работает рекурсия, но и понимать метод String. вот пример кода, который я использовал для его достижения: -

class PalindromeRecursive {
  public static void main(String[] args) {


    Scanner sc=new Scanner(System.in);
    System.out.println("Enter a string");
    String input=sc.next();
    System.out.println("is "+ input + "a palindrome : " +  isPalindrome(input));


  }

  public static  boolean isPalindrome(String s)
  {
    int low=0;
    int high=s.length()-1;
    while(low<high)
    {
      if(s.charAt(low)!=s.charAt(high))
      return false;
      isPalindrome(s.substring(low++,high--));
    }

    return true;
  }
}
person kaka musili    schedule 22.08.2018

person    schedule
comment
Добро пожаловать в stackoverflow.com. Этой теме несколько лет. Лучше не воскрешать старые темы, если ответ не внес значительного улучшения по сравнению с предыдущими ответами. - person Leigh; 10.04.2012

person    schedule
comment
Добро пожаловать в SO, ответы должны содержать объяснение того, что вы делаете/почему вы реализовали это таким образом. - person Aboutblank; 17.06.2013