Контрольная строка для палиндрома

на палиндром - это слово, фраза, число или другая последовательность единиц, которые могут быть прочитаны одинаково в любом направлении.

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

вот мой код:

public class Aufg1 {
    public static void main(String[] args) {
        String wort = "reliefpfpfeiller";
        char[] warray = wort.toCharArray(); 
        System.out.println(istPalindrom(warray));       
    }

    public static boolean istPalindrom(char[] wort){
        boolean palindrom = false;
        if(wort.length%2 == 0){
            for(int i = 0; i < wort.length/2-1; i++){
                if(wort[i] != wort[wort.length-i-1]){
                    return false;
                }else{
                    palindrom = true;
                }
            }
        }else{
            for(int i = 0; i < (wort.length-1)/2-1; i++){
                if(wort[i] != wort[wort.length-i-1]){
                    return false;
                }else{
                    palindrom = true;
                }
            }
        }
        return palindrom;
    }
}

30 ответов


почему не просто:

public static boolean istPalindrom(char[] word){
    int i1 = 0;
    int i2 = word.length - 1;
    while (i2 > i1) {
        if (word[i1] != word[i2]) {
            return false;
        }
        ++i1;
        --i2;
    }
    return true;
}

пример:

вход "andna".
i1 будет 0, а i2 будет 4.

первая итерация цикла мы сравним word[0] и word[4]. Они равны, поэтому мы увеличиваем i1 (теперь 1) и уменьшаем i2 (теперь 3).
Тогда мы сравним n. Они равны, поэтому мы увеличиваем i1 (теперь это 2) и уменьшаем i2 (это 2).
Теперь i1 и i2 равны (они оба 2), поэтому условие для хотя цикл больше не является истинным, цикл завершается, и мы возвращаем true.


вы можете проверить, является ли строка палиндромом, сравнивая ее с обратной стороной:

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

или для версий Java ранее, чем 1.5,

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

EDIT: @FernandoPelliccioni при условии очень тщательный анализ эффективности (или ее отсутствия) этого решения, как с точки зрения времени, так и с точки зрения пространства. Если вас интересует вычислительная сложность этого и других возможных решений этого вопроса, пожалуйста, прочитайте это!


сжатая версия, которая не включает (неэффективно) инициализацию группы объектов:

boolean isPalindrome(String str) {    
    int n = str.length();
    for( int i = 0; i < n/2; i++ )
        if (str.charAt(i) != str.charAt(n-i-1)) return false;
    return true;    
}

кроме того, рекурсия.

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

private boolean isPalindrome(String s) {
    int length = s.length();

    if (length < 2) // If the string only has 1 char or is empty
        return true;
    else {
        // Check opposite ends of the string for equality
        if (s.charAt(0) != s.charAt(length - 1))
            return false;
        // Function call for string with the two ends snipped off
        else
            return isPalindrome(s.substring(1, length - 1));
    }
}

или даже короче, если вы хотите:

private boolean isPalindrome(String s) {
    int length = s.length();
    if (length < 2) return true;
    else return s.charAt(0) != s.charAt(length - 1) ? false :
            isPalindrome(s.substring(1, length - 1));
}

Go, Java:

public boolean isPalindrome (String word) {
    String myWord = word.replaceAll("\s+","");
    String reverse = new StringBuffer(myWord).reverse().toString();
    return reverse.equalsIgnoreCase(myWord);
}

isPalindrome("Never Odd or Even"); // True
isPalindrome("Never Odd or Even1"); // False

другое ищу решение:

public static boolean isPalindrome(String s) {

        for (int i=0 , j=s.length()-1 ; i<j ; i++ , j-- ) {

            if ( s.charAt(i) != s.charAt(j) ) {
                return false;
            }
        }

        return true;
    }

public class Aufg1 {
    public static void main(String[] args) {
         String wort = "reliefpfpfeiller";
         char[] warray = wort.toCharArray(); 
         System.out.println(istPalindrom(warray));       
    }

    public static boolean istPalindrom(char[] wort){
        if(wort.length%2 == 0){
            for(int i = 0; i < wort.length/2-1; i++){
                if(wort[i] != wort[wort.length-i-1]){
                    return false;
                }
            }
        }else{
            for(int i = 0; i < (wort.length-1)/2-1; i++){
                if(wort[i] != wort[wort.length-i-1]){
                    return false;
                }
            }
        }
        return true;
    }
}

и здесь полная Java 8 потокового решение. Ан IntStream предоставляет все индексы до половины длины строк, а затем выполняется сравнение с начала и с конца.

public static void main(String[] args) {
    for (String testStr : Arrays.asList("testset", "none", "andna", "haah", "habh", "haaah")) {
        System.out.println("testing " + testStr + " is palindrome=" + isPalindrome(testStr));
    }
}

public static boolean isPalindrome(String str) {
    return IntStream.range(0, str.length() / 2)
            .noneMatch(i -> str.charAt(i) != str.charAt(str.length() - i - 1));
}

вывод:

testing testset is palindrome=true
testing none is palindrome=false
testing andna is palindrome=true
testing haah is palindrome=true
testing habh is palindrome=false
testing haaah is palindrome=true

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

public int isPalindrome(String a) {
        //Remove all spaces and non alpha characters
        String ab = a.replaceAll("[^A-Za-z0-9]", "").toLowerCase();
        //System.out.println(ab);

        for (int i=0; i<ab.length()/2; i++) {
            if(ab.charAt(i) != ab.charAt((ab.length()-1)-i)) {
                return 0;
            }
        }   
        return 1;
    }

public class palindrome {
public static void main(String[] args) {
    StringBuffer strBuf1 = new StringBuffer("malayalam");
    StringBuffer strBuf2 = new StringBuffer("malayalam");
    strBuf2.reverse();


    System.out.println(strBuf2);
    System.out.println((strBuf1.toString()).equals(strBuf2.toString()));
    if ((strBuf1.toString()).equals(strBuf2.toString()))
        System.out.println("palindrome");
    else
        System.out.println("not a palindrome");
}

}


Я работал над решением вопроса, который был отмечен как дубликат этого. С таким же успехом можно бросить его сюда...

вопрос просил одну строку, чтобы решить эту проблему, и я взял ее больше как литературный палиндром - так что пробелы, пунктуация и верхний/нижний регистр могут сбросить результат.

вот уродливое решение с небольшим тестовым классом:

public class Palindrome {
   public static boolean isPalendrome(String arg) {
         return arg.replaceAll("[^A-Za-z]", "").equalsIgnoreCase(new StringBuilder(arg).reverse().toString().replaceAll("[^A-Za-z]", ""));
   }
   public static void main(String[] args) {
      System.out.println(isPalendrome("hiya"));
      System.out.println(isPalendrome("star buttons not tub rats"));
      System.out.println(isPalendrome("stab nail at ill Italian bats!"));
      return;
   }
}

Извините, что это неприятно, но в другом вопросе указан однострочный.


удивительно, сколько существует различных решений такой простой проблемы! Вот еще один.

private static boolean palindrome(String s){
    String revS = "";
    String checkS = s.toLowerCase();
    String[] checkSArr = checkS.split("");

    for(String e : checkSArr){
        revS = e + revS;
    }

    return (checkS.equals(revS)) ? true : false;
}

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

import java.util.*;
    public class str {

        public static void main(String args[])
        {
          Scanner in=new Scanner(System.in);
          System.out.println("ENTER YOUR STRING: ");
          String a=in.nextLine();
          System.out.println("GIVEN STRING IS: "+a);
          StringBuffer str=new StringBuffer(a);
          StringBuffer str2=new StringBuffer(str.reverse());
          String s2=new String(str2);
          System.out.println("THE REVERSED STRING IS: "+str2);
            if(a.equals(s2))    
                System.out.println("ITS A PALINDROME");
            else
                System.out.println("ITS NOT A PALINDROME");
            }
    }

Я новичок в Java, и я принимаю ваш вопрос как вызов, чтобы улучшить мои знания.

import java.util.ArrayList;
import java.util.List;

public class PalindromeRecursiveBoolean {

    public static boolean isPalindrome(String str) {

        str = str.toUpperCase();
        char[] strChars = str.toCharArray();

        List<Character> word = new ArrayList<>();
        for (char c : strChars) {
            word.add(c);
        }

        while (true) {
            if ((word.size() == 1) || (word.size() == 0)) {
                return true;
            }
            if (word.get(0) == word.get(word.size() - 1)) {
                word.remove(0);
                word.remove(word.size() - 1);
            } else {
                return false;

            }

        }
    }
}
  1. если строка не состоит из букв или только одной буквы, это палиндром.
  2. в противном случае сравните первую и последнюю буквы строки.
    • если первая и последняя буквы отличаются, то строка не является палиндромом
    • в противном случае, первая и последняя буквы одинаковые. Удалите их из строки и определите, оставшаяся строка - это палиндром. Возьмите ответ для этой меньшей строки и используйте его в качестве ответа для исходной строки, а затем повторите из 1.

public boolean isPalindrome(String abc){
    if(abc != null && abc.length() > 0){
        char[] arr = abc.toCharArray();
        for (int i = 0; i < arr.length/2; i++) {
            if(arr[i] != arr[arr.length - 1 - i]){
                return false;
            }
        }
        return true;
    }
    return false;
}

другой способ-использовать массив char

public class Palindrome {

public static void main(String[] args) {
    String str = "madam";
    if(isPalindrome(str)) {
        System.out.println("Palindrome");
    } else {
        System.out.println("Not a Palindrome");
    }
}

private static boolean isPalindrome(String str) {
    // Convert String to char array
    char[] charArray = str.toCharArray();  
    for(int i=0; i < str.length(); i++) {
        if(charArray[i] != charArray[(str.length()-1) - i]) {
            return false;
        }
    }
    return true;
}

}


вот мой анализ ответа @Greg:componentsprogramming.com/palindromes


Sidenote: но, для меня важно сделать его в родовые пути. Требования заключаются в том, что последовательность является двунаправленной итерацией, а элементы последовательности сопоставимы с использованием равенства. Я не знаю, как это сделать на Java, но вот версия c++, я не знаю лучшего способа сделать это для двунаправленного последовательности.

template <BidirectionalIterator I> 
    requires( EqualityComparable< ValueType<I> > ) 
bool palindrome( I first, I last ) 
{ 
    I m = middle(first, last); 
    auto rfirst = boost::make_reverse_iterator(last); 
    return std::equal(first, m, rfirst); 
} 

сложность: линейное время,

  • Если я RandomAccessIterator: пол(н/2) comparissons и пол(н/2)*2 итераций

  • Если I является двунаправленным: пол(н/2) comparissons и пол(н/2)*2 итераций плюс ( 3/2)*n итераций, чтобы найти среднюю (среднюю функцию )

  • хранение: O (1)

  • не выделено dymamic память!--4-->



недавно я написал программу палиндрома, которая не использует StringBuilder. Поздний ответ, но это может пригодиться некоторым людям.

public boolean isPalindrome(String value) {
    boolean isPalindrome = true;
    for (int i = 0 , j = value.length() - 1 ; i < j ; i ++ , j --) {
        if (value.charAt(i) != value.charAt(j)) {
            isPalindrome = false;
        }
    }
    return isPalindrome;
}

используя стек, это можно сделать такой

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
import java.util.*;

public class Solution {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str=in.nextLine();
        str.replaceAll("\s+","");
        //System.out.println(str);
        Stack<String> stack=new Stack<String>();
        stack.push(str);
        String str_rev=stack.pop();
        if(str.equals(str_rev)){
            System.out.println("Palindrome"); 
        }else{
             System.out.println("Not Palindrome");
        }
    }
}

 public static boolean isPalindrome(String word) {
    String str = "";
    for (int i=word.length()-1; i>=0;  i--){
        str = str + word.charAt(i);
    }
   if(str.equalsIgnoreCase(word)){
       return true;
   }else{
       return false;
   }

}

import java.util.Scanner;


public class Palindrom {

    public static void main(String []args)
    {
        Scanner in = new Scanner(System.in);
        String str= in.nextLine();
        int x= str.length();

        if(x%2!=0)
        {
            for(int i=0;i<x/2;i++)
            {

                if(str.charAt(i)==str.charAt(x-1-i))
                {
                    continue;
                }
                else 
                {
                    System.out.println("String is not a palindrom");
                    break;
                }
            }
        }
        else
        {
            for(int i=0;i<=x/2;i++)
            {
                if(str.charAt(i)==str.charAt(x-1-i))
                {
                    continue;
                }
                else 
                {
                    System.out.println("String is not a palindrom");
                    break;
                }

            }
        }
    }

}

private static boolean isPalindrome(String word) {

        int z = word.length();
        boolean isPalindrome = false;

        for (int i = 0; i <= word.length() / 2; i++) {
            if (word.charAt(i) == word.charAt(--z)) {
                isPalindrome = true;
            }
        }

        return isPalindrome;
    }

Я ищу решение, которое не только палиндромы, как...

  • "каяк"
  • "мадам"

...но и для него тоже...


    учитывая не Буквы в словах

    public static boolean palindromeWords(String s ){
    
            int left=0;
            int right=s.length()-1;
    
            while(left<=right){
    
                while(left<right && !Character.isLetter(s.charAt(left))){
                    left++;
                }
                while(right>0 && !Character.isLetter(s.charAt(right))){
                    right--;
                }
    
                if((s.charAt(left++))!=(s.charAt(right--))){
                    return false;
                }
            }
            return true;
        }
    

    - - -

    @Test
    public void testPalindromeWords(){
        assertTrue(StringExercise.palindromeWords("ece"));
        assertTrue(StringExercise.palindromeWords("kavak"));
        assertFalse(StringExercise.palindromeWords("kavakdf"));
        assertTrue(StringExercise.palindromeWords("akka"));
        assertTrue(StringExercise.palindromeWords("??e@@c_--e"));
    }
    

    здесь вы можете проверить палиндром ряд строк динамически

    import java.util.Scanner;
    
    public class Checkpalindrome {
     public static void main(String args[]) {
      String original, reverse = "";
      Scanner in = new Scanner(System.in);
      System.out.println("Enter How Many number of Input you want : ");
      int numOfInt = in.nextInt();
      original = in.nextLine();
    do {
      if (numOfInt == 0) {
        System.out.println("Your Input Conplete");
       } 
      else {
        System.out.println("Enter a string to check palindrome");
        original = in.nextLine();
    
        StringBuffer buffer = new StringBuffer(original);
        reverse = buffer.reverse().toString();
    
      if (original.equalsIgnoreCase(reverse)) {
        System.out.println("The entered string is Palindrome:"+reverse);
       } 
      else {
        System.out.println("The entered string is not Palindrome:"+reverse);
        }
     }
       numOfInt--;
        } while (numOfInt >= 0);
    }
    }
    

    IMO, рекурсивный способ является самым простым и ясным.

    public static boolean isPal(String s)
    {   
        if(s.length() == 0 || s.length() == 1)
            return true; 
        if(s.charAt(0) == s.charAt(s.length()-1))
           return isPal(s.substring(1, s.length()-1));                
       return false;
    }
    

    здесь, проверяя самый большой палиндром в строке, всегда начиная с 1-го символа.

    public static String largestPalindromeInString(String in) {
        int right = in.length() - 1;
        int left = 0;
        char[] word = in.toCharArray();
        while (right > left && word[right] != word[left]) {
            right--;
        }
        int lenght = right + 1;
        while (right > left && word[right] == word[left]) {
    
            left++;
            right--;
    
        }
        if (0 >= right - left) {
            return new String(Arrays.copyOf(word, lenght ));
        } else {
            return largestPalindromeInString(
                    new String(Arrays.copyOf(word, in.length() - 1)));
        }
    }
    

    Фрагмент Кода:

    import java.util.Scanner;
    
     class main
     {
        public static void main(String []args)
        {
           Scanner sc = new Scanner(System.in);
           String str = sc.next();
           String reverse = new StringBuffer(str).reverse().toString();
    
            if(str.equals(reverse))
                System.out.println("Pallindrome");
            else
                System.out.println("Not Pallindrome");
         }
    }
    

    enter image description here

    import java.util.Collections;
    import java.util.HashSet;
    import java.util.Scanner;
    import java.util.Set;
    
    public class GetAllPalindromes 
    {
        static Scanner in;
    
        public static void main(String[] args) 
        {
            in = new Scanner(System.in);
            System.out.println("Enter a string \n");
            String abc = in.nextLine();
            Set a = printAllPalindromes(abc);
            System.out.println("set is   " + a);
        }
    
        public static Set<CharSequence> printAllPalindromes(String input) 
        {
            if (input.length() <= 2) {
                return Collections.emptySet();
            }
    
            Set<CharSequence> out = new HashSet<CharSequence>();
            int length = input.length();
    
            for (int i = 1; i < length - 1; i++) 
            {
                for (int j = i - 1, k = i + 1; j >= 0 && k < length; j--, k++) 
                {
                    if (input.charAt(j) == input.charAt(k)) {
                        out.add(input.subSequence(j, k + 1));
                    } else {
                        break;
                    }
                }
            }
            return out;
        }
    }
    
    **Get All Palindrome in s given string**
    

    выход D:\Java > Java GetAllPalindromes Введите строку

    Привет пользователь Нитин-мой лучший друг вау !

    ответ набор [Нитин, Нитин, вау, вау, iti]

    D:\Java>


    For-loop содержит sub.length() / 2 - 1 . Он должен быть вычитан с 1, так как элемент в середине строки не должен проверяться.

    например, если мы должны проверить строку с 7 символами (1234567), то 7/2 => 3, а затем мы вычитаем 1, и поэтому позиции в строке станут (0123456). Символы, проверенные с помощью элемента 0, 1, 2 с 6, 5, 4 соответственно. Нас не волнует элемент в позиции 3, так как он находится точно посередине строки.

     private boolean isPalindromic(String sub) {
            for (int i = 0; i <= sub.length() / 2 - 1; i++) {
                if (sub.charAt(i) != sub.charAt(sub.length() - 1 - i)) {
                    return false;
                }
            }
            return true;
        }