Periksa string untuk palindrom


94

Sebuah palindrom adalah kata, frase, nomor atau urutan lainnya dari unit yang bisa dibaca dengan cara yang sama di kedua arah.

Untuk memeriksa apakah sebuah kata adalah palindrome, saya mendapatkan array karakter dari kata tersebut dan membandingkan karakternya. Saya mengujinya dan tampaknya berhasil. Namun saya ingin tahu apakah itu benar atau apakah ada sesuatu yang perlu diperbaiki.

Ini kode saya:

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;
    }
}

4
Tidak yakin apakah ini disengaja tetapi string dalam contoh Anda - reliefpfpfeiller - bukan palindrome
barrowc

Jawaban:


186

Mengapa tidak hanya:

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;
}

Contoh:

Inputnya adalah "andna".
i1 akan menjadi 0 dan i2 akan menjadi 4.

Iterasi loop pertama kita akan membandingkan word[0]dan word[4]. Mereka sama, jadi kami menambah i1 (sekarang 1) dan menurunkan i2 (sekarang 3).
Jadi kami kemudian membandingkan n. Mereka sama, jadi kami menambah i1 (sekarang 2) dan menurunkan i2 (jadi 2).
Sekarang i1 dan i2 sama (keduanya 2), jadi kondisi untuk while loop tidak lagi benar sehingga loop berakhir dan kita mengembalikan true.


1
Selain pre increment (++ i1 dan --i2), kita juga bisa menggunakan post increment (i1 ++, i2 -) hasilnya sama ya!
pengguna0946076422

@ user0946076422 Ya. Saya juga merasa seperti itu. Akan lebih bagus jika OP memiliki penjelasan yang berbeda.
Vijay Tholpadi

3
@Vijay Tholpadi - Ini benar-benar preferensi pengkodean lebih dari apa pun. Kenaikan posting akan mencapai hasil yang sama dalam contoh khusus ini, tetapi saya selalu menggunakan kenaikan awal kecuali ada alasan khusus untuk tidak melakukannya.
dcp

118

Anda dapat memeriksa apakah suatu string adalah palindrom dengan membandingkannya dengan kebalikannya:

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

atau untuk versi Java lebih awal dari 1.5,

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

EDIT: @FernandoPelliccioni memberikan analisis yang sangat menyeluruh tentang efisiensi (atau ketiadaan) solusi ini, baik dari segi waktu dan ruang. Jika Anda tertarik dengan kompleksitas komputasi ini dan kemungkinan solusi lain untuk pertanyaan ini, bacalah!


10
Bandingkan kompleksitas algoritme Anda dengan algoritme lain.
Fernando Pelliccioni

2
@FernandoPelliccioni, menurut saya kompleksitasnya sama dengan solusi lainnya, bukan?
aioobe

1
@Fernando, sejauh yang saya tahu semua jawaban memiliki kompleksitas linier. Karena itu, tidak ada cara untuk memberikan jawaban pasti tentang solusi mana yang paling efisien. Anda dapat menjalankan benchmark tetapi mereka akan spesifik untuk JVM dan JRE tertentu. Semoga berhasil dengan postingan blog Anda. Menantikan untuk dibaca.
aioobe

1
@FernandoPelliccioni Ini adalah ungkapan untuk seseorang yang cerdas, pandai, mampu menemukan solusi untuk situasi sulit. :-)
Sipty

1
@FernandoPelliccioni analisis yang bagus
Saravana

66

Versi ringkas, yang tidak melibatkan (secara tidak efisien) menginisialisasi banyak objek:

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;    
}

18

Alternatifnya, rekursi .

Untuk siapa saja yang mencari solusi rekursif yang lebih pendek, untuk memeriksa apakah string yang diberikan memenuhi palindrome:

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));
    }
}

ATAU bahkan lebih pendek , jika Anda suka:

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

3
Kode bagus, rekursi membuatnya sangat mudah dan lebih sedikit baris pada kode.
Akash5288

2
versi yang lebih pendek dapat disederhanakan:return s.charAt(0) == s.charAt(l - 1) && isPalindrome(s.substring(1, l - 1));
vault

10

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

Ini tampaknya solusi termudah dan paling langsung bagi saya. Terima kasih!
RShome

4

juga solusi yang tampak berbeda:

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;
    }

4

Dan berikut solusi streaming Java 8 yang lengkap. Sebuah IntStream menyediakan semua indeks hingga string setengah panjang dan kemudian perbandingan dari awal dan akhir dilakukan.

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));
}

Outputnya adalah:

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

1
Kenapa tidak allMatchdengan allMatch(i -> str.charAt(i) == str.charAt(str.length() - i - 1))?
gil.fernandes

4
public class Palindromes {
    public static void main(String[] args) {
         String word = "reliefpfpfeiller";
         char[] warray = word.toCharArray(); 
         System.out.println(isPalindrome(warray));       
    }

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

2
sedikit disederhanakan. tapi saya suka jawaban dcp!
Casey

Sudahkah Anda mencoba berlari isPalindrome()dengan "cbb"?
kenshinji

3
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");
}

}


3

Saya mengerjakan solusi untuk pertanyaan yang ditandai sebagai duplikat dari pertanyaan ini. Sebaiknya lemparkan ke sini ...

Pertanyaan tersebut meminta satu baris untuk menyelesaikannya, dan saya menganggapnya lebih sebagai palindrom sastra - sehingga spasi, tanda baca, dan huruf besar / kecil dapat menghilangkan hasilnya.

Inilah solusi jelek dengan kelas tes kecil:

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;
   }
}

Maaf, ini agak menjijikkan - tetapi pertanyaan lain menyebutkan satu kalimat.


1
Penasaran saja, kenapa operator terner di ujung?
mengetikduck

Sama sekali tidak ada - saya pasti belum minum kopi. Akan memperbaiki tanggapan saya - terima kasih !.
Marc

3

Memeriksa palindrom untuk paruh pertama string dengan sisanya, kasus ini mengasumsikan penghapusan spasi putih.

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;
    }

2

Saya baru mengenal java dan menjawab pertanyaan Anda sebagai tantangan untuk meningkatkan pengetahuan saya.

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. Jika string tidak terbuat dari huruf atau hanya satu huruf, itu adalah palindrome.
  2. Jika tidak, bandingkan huruf pertama dan terakhir dari string tersebut.
    • Jika huruf pertama dan terakhir berbeda, maka string tersebut bukan palindrome
    • Jika tidak, huruf pertama dan terakhir sama. Lepaskan mereka dari string, dan tentukan apakah string yang tersisa adalah palindrome. Ambil jawaban untuk string yang lebih kecil ini dan gunakan sebagai jawaban untuk string aslinya lalu ulangi dari 1 .

1

Coba ini:

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");
            }
    }

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;
}

1

Cara lain adalah dengan menggunakan char Array

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;
}

}


1
Pendekatan ini sangat bagus. Kompleksitas Waktu O (n), Kompleksitas ruang O (1)
kanaparthikiran

1

Berikut analisis saya tentang jawaban @Greg: componentsprogramming.com/palindromes


Sidenote: Tapi, bagi saya penting untuk melakukannya dengan cara Generik . Persyaratannya adalah bahwa urutannya dapat diulang dua arah dan elemen urutannya dapat dibandingkan menggunakan persamaan. Saya tidak tahu bagaimana melakukannya di Java, tetapi, ini adalah versi C ++, saya tidak tahu cara yang lebih baik untuk melakukannya untuk urutan dua arah.

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); 
} 

Kompleksitas: waktu linier,

  • Jika saya adalah RandomAccessIterator: floor (n / 2) comparissons dan floor (n / 2) * 2 iterations

  • Jika I adalah BidirectionalIterator: floor (n / 2) comparissons dan floor (n / 2) * 2 iterations plus (3/2) * n iterations untuk mencari tengah (fungsi tengah)

  • penyimpanan: O (1)

  • Tidak ada memori yang dialokasikan dymamic



1

Baru-baru ini saya menulis program palindrome yang tidak menggunakan StringBuilder. Jawaban yang terlambat tetapi ini mungkin berguna bagi sebagian orang.

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;
}

1

Menggunakan stack, bisa dilakukan seperti ini

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");
        }
    }
}

karena Anda harus mengetahui bahwa, tumpukan adalah tipe LIFO yang berarti Anda pada dasarnya mendorong data melalui awal tumpukan dan mengambil data dari akhir tumpukan menggunakan pop (). Semoga ini membantu!
aayushi

1
 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;
   }

}

1

Sungguh menakjubkan betapa banyak solusi berbeda untuk masalah sederhana seperti itu! Ini satu lagi.

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;
}

1
  • Implementasi ini berfungsi untuk angka dan string.
  • Karena kita tidak menulis apapun, jadi tidak perlu mengubah string menjadi array karakter.
public static boolean isPalindrome(Object obj)
{
    String s = String.valueOf(obj);

    for(int left=0, right=s.length()-1; left < right; left++,right--)
    {
        if(s.charAt(left++) != s.charAt(right--))
            return false;
    }
    return true;
}

1

Mengapa tidak hanya:

boolean isPalindrom(String s) {
        char[] myChars = s.toCharArray();
        for (int i = 0; i < myChars.length/2; i++) {
            if (myChars[i] != myChars[myChars.length - 1 - i]) {
                return false;
            }
        }
        return true;
}

0
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;
                }

            }
        }
    }

}

0
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;
    }

0

Saya mencari solusi yang tidak hanya bekerja untuk palindrom seperti ...

  • "Kayak"
  • "Nyonya"

... tapi juga untuk ...

  • "Seorang pria, rencana, kanal, Panama!"
  • "Apakah itu mobil atau kucing yang saya lihat?"
  • "Tidak ada 'x' di Nixon"

Iteratif : Ini telah terbukti sebagai solusi yang baik.

private boolean isPalindromeIterative(final String string)
    {
        final char[] characters =
            string.replaceAll("[\\W]", "").toLowerCase().toCharArray();

        int iteratorLeft = 0;
        int iteratorEnd = characters.length - 1;

        while (iteratorEnd > iteratorLeft)
        {
            if (characters[iteratorLeft++] != characters[iteratorEnd--])
            {
                return false;
            }
        }

        return true;
    }

Rekursif . Saya pikir solusi ini seharusnya tidak lebih buruk daripada yang berulang. Agak merepotkan kita perlu mengekstrak langkah pembersihan dari metode untuk menghindari pemrosesan yang tidak perlu.

private boolean isPalindromeRecursive(final String string)
        {
            final String cleanString = string.replaceAll("[\\W]", "").toLowerCase();
            return isPalindromeRecursiveRecursion(cleanString);
        }

private boolean isPalindromeRecursiveRecursion(final String cleanString)
        {
            final int cleanStringLength = cleanString.length();

            return cleanStringLength <= 1 || cleanString.charAt(0) ==
                       cleanString.charAt(cleanStringLength - 1) &&
                       isPalindromeRecursiveRecursion  
                           (cleanString.substring(1, cleanStringLength - 1));
        }

Membalik : Ini telah terbukti sebagai solusi yang mahal.

private boolean isPalindromeReversing(final String string)
    {
        final String cleanString = string.replaceAll("[\\W]", "").toLowerCase();
        return cleanString.equals(new StringBuilder(cleanString).reverse().toString());
    }

Semua penghargaan untuk orang-orang yang menjawab di posting ini dan menjelaskan topik ini.


0

Mempertimbangkan bukan huruf dalam kata-kata

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"));
}

0

Di sini Anda dapat memeriksa palindrome sejumlah String secara dinamis

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);
}
}

0

IMO, cara rekursif adalah yang paling sederhana dan paling jelas.

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;
}

2
Ini sudah digunakan dalam jawaban: Periksa string untuk palindrome (hanya catatan)
Tom

maaf, saya melewatkannya.
john Smith

0

di sini, memeriksa palindrom terbesar dalam sebuah string, selalu dimulai dari karakter pertama.

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)));
    }
}

0

Cuplikan Kode:

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");
     }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.