Palindrom için dizeyi kontrol edin


94

Bir palindrom bir kelime, deyim, sayı veya her iki yönde aynı şekilde okunabilir birimlerin diğer dizisidir.

Bir kelimenin bir palindrom olup olmadığını kontrol etmek için, kelimenin karakter dizisini alırım ve karakterleri karşılaştırırım. Test ettim ve işe yarıyor gibi görünüyor. Ancak bunun doğru olup olmadığını veya iyileştirilecek bir şey olup olmadığını bilmek istiyorum.

İşte kodum:

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
Bunun kasıtlı olup olmadığından emin değilim, ancak örneğinizdeki dize - Relipfpfeiller - bir palindrom değil
barrowc

Yanıtlar:


186

Neden sadece:

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

Misal:

Giriş "andna" dır.
i1 0 ve i2 4 olacaktır.

İlk döngü yinelemesini karşılaştıracağız word[0]ve word[4]. Eşittirler, bu yüzden i1'i artırırız (şimdi 1'dir) ve i2'yi düşürürüz (şimdi 3'tür).
Böylece n'leri karşılaştırırız. Eşittirler, bu yüzden i1'i artırırız (şimdi 2'dir) ve i2'yi düşürürüz (2'dir).
Şimdi i1 ve i2 eşittir (ikisi de 2'dir), dolayısıyla while döngüsünün koşulu artık doğru değildir, bu nedenle döngü sona erer ve doğruya döneriz.


1
Ön artış (++ i1 ve --i2) yerine, artım (i1 ++, i2 -) sonucunu da kullanabiliriz sanırım!
user0946076422

@ user0946076422 Evet. Ben de öyle hissettim. OP'nin farklı bir açıklaması varsa harika olur.
Vijay Tholpadi

3
@Vijay Tholpadi - Her şeyden çok gerçekten bir kodlama tercihi. Sonradan artış, bu belirli örnekte aynı sonucu verir, ancak bunu yapmamak için belirli bir neden olmadıkça her zaman ön artış kullanırım.
dcp

118

Bir dizenin palindrom olup olmadığını kendi tersiyle karşılaştırarak kontrol edebilirsiniz:

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

veya Java'nın 1.5'ten önceki sürümleri için,

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

DÜZENLEME: @FernandoPelliccioni , bu çözümün hem zaman hem de mekan açısından verimliliğinin (veya eksikliğinin) çok kapsamlı bir analizini sağladı . Bunun hesaplama karmaşıklığı ve bu sorunun olası diğer çözümleriyle ilgileniyorsanız, lütfen okuyun!


10
Algoritmanızın karmaşıklığını diğerlerine göre karşılaştırın.
Fernando Pelliccioni

2
@FernandoPelliccioni, bence diğer çözümlerle aynı karmaşıklık, değil mi?
aioobe

1
@Fernando, anlayabildiğim kadarıyla tüm cevapların doğrusal bir karmaşıklığı var. Bu nedenle, hangi çözümün en verimli olduğuna kesin bir yanıt vermenin bir yolu yoktur. Karşılaştırmalar çalıştırabilirsiniz, ancak bunlar belirli bir JVM ve JRE'ye özgü olacaktır. Blog yayınınızda iyi şanslar. Okumayı dört gözle bekliyorum.
aioobe

1
@FernandoPelliccioni Zeki, zeki, zor durumlara çözüm bulabilen biri için bir deyimdir. :-)
Sipty

1
@FernandoPelliccioni güzel analiz
Saravana

67

Bir grup nesneyi başlatmayı (verimsiz bir şekilde) içermeyen kısa bir sürüm:

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

Alternatif olarak, özyineleme .

Daha kısa özyinelemeli bir çözüm arayanlar için, belirli bir dizenin bir palindrom olarak tatmin edici olup olmadığını kontrol etmek için:

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

VEYA daha da kısa , isterseniz:

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
Güzel kod, özyineleme onu gerçekten kolaylaştırır ve kodda daha az satır olmasını sağlar.
Akash5288

2
daha kısa versiyon basitleştirilebilir:return s.charAt(0) == s.charAt(l - 1) && isPalindrome(s.substring(1, l - 1));
kasa

10

Git, 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

Bunlar bana en kolay ve en açık çözüm gibi geldi. Teşekkürler!
RShome

4

ayrıca farklı görünümlü bir çözüm:

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

Ve burada eksiksiz bir Java 8 akış çözümü. Bir IntStream dizeleri yarı uzunlukta tüm dizinleri sağlar ve ardından baştan ve sondan bir karşılaştırma yapılır.

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

Çıktı:

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
Neden olmasın allMatchile 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
biraz basitleştirildi. ama dcp'nin cevabını beğendim!
Casey

Çalıştırdığınız denediniz isPalindrome()ile "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

Bunun kopyası olarak işaretlenen bir soru için bir çözüm üzerinde çalıştım. Buraya atsan iyi olur ...

Soru, bunu çözmek için tek bir satır istedi ve ben daha çok edebi palindrom olarak aldım - yani boşluklar, noktalama işaretleri ve büyük / küçük harf sonucu atlayabilir.

İşte küçük bir test sınıfıyla çirkin çözüm:

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

Maalesef biraz iğrenç - ama diğer soru tek satırlık bir soruyu belirtti.


1
Merak ediyorum, neden sonunda üçlü operatör?
typingduck

Kesinlikle hiçbir şey - kahvemi içmemiş olmalıyım. Cevabımı düzeltecek - teşekkürler !.
Marc

3

Geri kalanıyla dizenin ilk yarısı için palindrom kontrol edildiğinde, bu durum beyaz boşlukların kaldırıldığını varsayar.

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

Java konusunda yeniyim ve sorunuzu bilgimi geliştirmek için bir meydan okuma olarak ele alıyorum.

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. Dize hiçbir harften veya tek bir harften oluşuyorsa, bu bir palindromdur.
  2. Aksi takdirde, dizenin ilk ve son harflerini karşılaştırın.
    • İlk ve son harfler farklıysa, dize bir palindrom değildir
    • Aksi takdirde ilk ve son harfler aynıdır. Bunları dizeden ayırın ve kalan dizenin bir palindrom olup olmadığını belirleyin. Bu daha küçük dizenin yanıtını alın ve orijinal dizenin yanıtı olarak kullanın, ardından 1'den itibaren tekrarlayın .

1

Şunu deneyin:

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

Başka bir yol da char Array kullanmaktır

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
Bu yaklaşım mükemmel. Zaman Karmaşıklığı O (n), uzay Karmaşıklığı O (1)
kanaparthikiran

1

İşte @Greg cevabının analizi: componentsprogramming.com/palindromes


Sidenote: Ama benim için bunu Genel bir şekilde yapmak önemli . Gereksinimler, dizinin çift yönlü yinelenebilir olması ve dizinin öğelerinin eşitlik kullanılarak karşılaştırılabilir olmasıdır. Bunu Java'da nasıl yapacağımı bilmiyorum, ama burada bir C ++ sürümü var, bunu çift yönlü diziler için yapmanın daha iyi bir yolunu bilmiyorum.

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

Karmaşıklık: doğrusal zaman,

  • I RandomAccessIterator ise: kat (n / 2) karşılaştırmaları ve kat (n / 2) * 2 yineleme

  • I, Çift Yönlü Yineleyici ise: kat (n / 2) karşılaştırmaları ve kat (n / 2) * 2 yineleme artı (3/2) * n yineleme (orta işlev) bulmak için

  • depolama: O (1)

  • Dymamik ayrılmış bellek yok



1

Geçenlerde StringBuilder kullanmayan bir palindrome programı yazdım. Geç bir cevap ama bu bazı insanlar için kullanışlı olabilir.

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

Stack kullanarak şu şekilde yapılabilir

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

Bunu bilmeniz gerektiği gibi, yığın LIFO tipindedir, yani temelde verileri yığının başlangıcına itiyorsunuz ve pop () kullanarak yığının sonundan veri alıyorsunuz demektir. Bu yardımcı olur umarım!
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

Böylesine basit bir soruna kaç farklı çözüm bulunması şaşırtıcı! İşte burada bir başkası.

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
  • Bu uygulama sayılar ve dizeler için çalışır.
  • Hiçbir şey yazmadığımız için dizeyi karakter dizisine dönüştürmeye gerek yoktur.
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

Neden sadece:

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

Sadece palindromlar için işe yaramayan bir çözüm arıyordum ...

  • "Kayık"
  • "Madam"

... ama aynı zamanda ...

  • "Bir adam, bir plan, bir kanal, Panama!"
  • "Gördüğüm bir araba mı yoksa kedi miydi?"
  • "Nixon'da" x "yok"

Yinelemeli : Bunun iyi bir çözüm olduğu kanıtlanmıştır.

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

Özyinelemeli . Bu çözümün yinelemeli olandan çok daha kötü olmaması gerektiğini düşünüyorum. Gereksiz işlemden kaçınmak için temizleme adımını yöntemden çıkarmamız gerekiyor.

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

Tersine çevirme : Bunun pahalı bir çözüm olduğu kanıtlanmıştır.

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

Bu yazıda cevap veren ve konuya ışık tutan adamlara tüm krediler.


0

Kelimelerdeki harfleri dikkate almamak

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

Burada palindromu dinamik olarak bir dizi String kontrol edebilirsiniz.

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, özyinelemeli yol en basit ve en net olanıdır.

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
Bu zaten bir yanıtta kullanıldı: Palindrom için dizeyi kontrol et (sadece bir not)
Tom

üzgünüm, kaçırdım.
john Smith

0

burada, her zaman 1. karakterden başlayarak bir dizedeki en büyük palindromu kontrol edin.

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

Kod Parçacığı:

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");
     }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.