Tulis fungsi yang mengembalikan palindrom terpanjang dalam string tertentu

102

mis. "ccddcc" dalam string "abaccddccefe"

Saya memikirkan solusi tetapi itu berjalan dalam waktu O (n ^ 2)

Algo 1:

Langkah-langkah: Ini adalah metode kekerasan

  1. Memiliki 2 untuk loop
    untuk i = 1 hingga i kurang dari array.length -1
    untuk j = i + 1 hingga j kurang dari array.length
  2. Dengan cara ini Anda bisa mendapatkan substring dari setiap kemungkinan kombinasi dari larik
  3. Memiliki fungsi palindrome yang memeriksa apakah suatu string adalah palindrome
  4. jadi untuk setiap substring (i, j) panggil fungsi ini, jika itu adalah palindrome simpan dalam variabel string
  5. Jika Anda menemukan substring palindrome berikutnya dan jika lebih besar dari yang sekarang, gantilah dengan yang sekarang.
  6. Akhirnya variabel string Anda akan memiliki jawabannya

Masalah: 1. Algo ini berjalan dalam waktu O (n ^ 2).

Algo 2:

  1. Balikkan string dan simpan dalam array yang berbeda
  2. Sekarang temukan substring terbesar yang cocok di antara kedua larik
  3. Tapi ini juga berjalan dalam waktu O (n ^ 2)

Bisakah kalian memikirkan algo yang berjalan di waktu yang lebih baik. Jika memungkinkan O (n) waktu

Pelajar
sumber
42
Saya pikir yang pertama adalah O(n^2)mendapatkan substring * O(n)untuk memeriksa apakah mereka palindrom, dengan total O(n^3)?
Skylar Saveland
Bagaimana jika saya tahu saya bekerja dengan palindrome dan menyimpan string saya sebagai dua bagian dan kemudian jika saya menggunakan Java, saya akan memeriksa O (1) untuk fungsinya?
viki.omega9
10
Secong algo benar? Bagaimana dengan string: "abcdecba". Substring terbesar yang cocok adalah ("abcdecba" vs. "abcedcba"): "abc" atau "cba". Namun, keduanya bukan palindrom.
Yarneo
@Pelajar, hanya ingin tahu, dalam langkah Anda di atas, larik apa yang Anda rujuk dalam loop for Anda? Dengan array, apakah Anda mengacu pada string? string.length?
Zolt
1
bagi mereka yang mencari jawaban dengan O (n ^ 2) - geeksforgeeks.org/longest-palindrome-substring-set-1
Shirish Herwade

Jawaban:

76

Anda dapat menemukan palindrom terpanjang menggunakan Algoritma Manacher ini di O(n)waktu! Penerapannya dapat ditemukan di sini dan di sini .

Untuk masukan String s = "HYTBCABADEFGHABCDEDCBAGHTFYW1234567887654321ZWETYGDE"ia menemukan keluaran yang benar yaitu 1234567887654321.

AnujKu
sumber
3
Saya tidak mengerti bagaimana ini linier. saya melihat whiletertanam di fordengan pembatas yang tampaknya mirip dengan lingkaran luar.
v.oddou
9

Algo 2 mungkin tidak berfungsi untuk semua string. Berikut adalah contoh string seperti "ABCDEFCBA".

Bukan berarti string tersebut memiliki "ABC" dan "CBA" sebagai substringnya. Jika Anda membalikkan string asli, itu akan menjadi "ABCFEDCBA". dan substring terpanjang yang cocok adalah "ABC" yang bukan palindrome.

Anda mungkin perlu juga memeriksa apakah substring terpanjang yang cocok ini sebenarnya adalah palindrome yang memiliki waktu berjalan O (n ^ 3).

VCB
sumber
2
Penting untuk dicatat bahwa Algo 2 harus bekerja untuk "palindrome urutan terpanjang yang cocok" yang merupakan masalah algoritme umum di mana karakter berikutnya juga dapat dipisahkan dalam string. Misalnya, urutan pencocokan terpanjang (termasuk pemisahan karakter) antara dua string di atas adalah "ABCFCBA" yang juga merupakan palindrome :) Berikut tautan yang menjelaskan masalah LCS: ics.uci.edu/~eppstein/161/960229.html
Jake Drew
5

Sejauh yang saya mengerti masalahnya, kita dapat menemukan palindrom di sekitar indeks tengah dan menjangkau pencarian kita dua arah, ke kanan dan kiri tengah. Mengingat itu dan mengetahui tidak ada palindrom di sudut masukan, kita dapat mengatur batas ke 1 dan panjang-1. Sambil memperhatikan batas minimum dan maksimum String, kami memverifikasi apakah karakter pada posisi indeks simetris (kanan dan kiri) sama untuk setiap posisi tengah hingga kami mencapai pusat batas atas maksimal kami.

Loop luar adalah O (n) (maks n-2 iterasi), dan loop dalam sementara adalah O (n) (max sekitar (n / 2) - 1 iterasi)

Berikut implementasi Java saya menggunakan contoh yang diberikan oleh pengguna lain.

class LongestPalindrome {

    /**
     * @param input is a String input
     * @return The longest palindrome found in the given input.
     */
    public static String getLongestPalindrome(final String input) {
        int rightIndex = 0, leftIndex = 0;
        String currentPalindrome = "", longestPalindrome = "";
        for (int centerIndex = 1; centerIndex < input.length() - 1; centerIndex++) {
            leftIndex = centerIndex - 1;  rightIndex = centerIndex + 1;
            while (leftIndex >= 0 && rightIndex < input.length()) {
                if (input.charAt(leftIndex) != input.charAt(rightIndex)) {
                    break;
                }
                currentPalindrome = input.substring(leftIndex, rightIndex + 1);
                longestPalindrome = currentPalindrome.length() > longestPalindrome.length() ? currentPalindrome : longestPalindrome;
                leftIndex--;  rightIndex++;
            }
        }
        return longestPalindrome;
    }

    public static void main(String ... args) {
        String str = "HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE";
        String longestPali = getLongestPalindrome(str);
        System.out.println("String: " + str);
        System.out.println("Longest Palindrome: " + longestPali);
    }
}

Output dari ini adalah sebagai berikut:

marcello:datastructures marcello$ javac LongestPalindrome
marcello:datastructures marcello$ java LongestPalindrome
String: HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE
Longest Palindrome: 12345678987654321
Marcello de Sales
sumber
6
Jika saya memberikan "HYTBCABADEFGHABCDEDCBAGHTFYW1234567887654321ZWETYGDE" Itu tidak berfungsi Tapi jawaban harus 1234567887654321
Elbek
1
@j_random_hacker tidak, itu salah satu solusi kuadrat. Itu tercakup di sini sebagai expandAroundCenter.
v.oddou
@ v.oddou: Anda benar sekali, dan saya tidak tahu bagaimana saya menyimpulkan O (n ^ 3) mengingat hanya ada 2 loop bersarang! Saya akan menghapus komentar yang salah itu ... Tetapi saya juga memperhatikan bahwa solusi ini memiliki masalah, yang akan saya letakkan di komentar terpisah sehingga penulis mudah-mudahan memperhatikan.
j_random_hacker
Klaim saya sebelumnya tentang kompleksitas waktu O (n ^ 3) salah (terima kasih @ v.oddou karena telah menunjukkan hal ini!) Tetapi ada masalah lain: kode ini tidak mempertimbangkan palindrom dengan panjang genap. Ini bisa diperbaiki dengan menambahkan loop luar kedua yang sangat mirip (juga O (n ^ 2) sehingga tidak mempengaruhi kompleksitas waktu O (n ^ 2)) yang memperluas palindrom di sekitar masing-masing posisi n-1 di antara masing - masing sepasang karakter. +2 jika Anda memperbaiki :)
j_random_hacker
2

dengan regex dan ruby ​​Anda dapat memindai palindrom pendek seperti ini:

PROMPT> irb
>> s = "longtextwithranynarpalindrome"
=> "longtextwithranynarpalindrome"
>> s =~ /((\w)(\w)(\w)(\w)(\w)\6\5\4\3\2)/; p $1
nil
=> nil
>> s =~ /((\w)(\w)(\w)(\w)\w\5\4\3\2)/; p $1
nil
=> nil
>> s =~ /((\w)(\w)(\w)(\w)\5\4\3\2)/; p $1
nil
=> nil
>> s =~ /((\w)(\w)(\w)\w\4\3\2)/; p $1
"ranynar"
=> nil
neoneye
sumber
2

Saya telah menulis program Java berikut karena penasaran, HTH yang sederhana dan cukup jelas. Terima kasih.

/**
 *
 * @author sanhn
 */
public class CheckPalindrome {

    private static String max_string = "";

    public static void checkSubString(String s){
        System.out.println("Got string is "+s);
        for(int i=1;i<=s.length();i++){
            StringBuilder s1 = new StringBuilder(s.substring(0,i));
            StringBuilder s2 = new StringBuilder(s.substring(0,i));
            s2.reverse();
            if(s1.toString().equals(s2.toString())){
                if(max_string.length()<=s1.length()){
                    max_string = s1.toString();
                    System.out.println("tmp max is "+max_string);
                }

            }
        }
    }

    public static void main(String[] args){
        String s="HYTBCABADEFGHABCDEDCBAGHTFYW1234567887654321ZWETYGDE";

        for(int i=0; i<s.length(); i++)
            checkSubString(s.substring(i, s.length()));

        System.out.println("Max string is "+max_string);
    }
}
Cleonjoys
sumber
1

Saya ditanyai pertanyaan ini baru-baru ini. Inilah solusi yang [akhirnya] saya dapatkan. Saya melakukannya dalam JavaScript karena cukup mudah dalam bahasa itu.

Konsep dasarnya adalah Anda berjalan di string mencari palindrom multi-karakter sekecil mungkin (baik dua atau tiga karakter satu). Setelah Anda memilikinya, perluas perbatasan di kedua sisi sampai berhenti menjadi palindrom. Jika panjang itu lebih panjang dari yang terpanjang saat ini, simpan dan lanjutkan.

// This does the expanding bit.
function getsize(s, start, end) {
    var count = 0, i, j;
    for (i = start, j = end; i >= 0 && j < s.length; i--, j++) {
        if (s[i] !== s[j]) {
            return count;
        }
        count = j - i + 1; // keeps track of how big the palindrome is
    }
    return count;
}

function getBiggestPalindrome(s) {
    // test for simple cases
    if (s === null || s === '') { return 0; }
    if (s.length === 1) { return 1; }
    var longest = 1;
    for (var i = 0; i < s.length - 1; i++) {
        var c = s[i]; // the current letter
        var l; // length of the palindrome
        if (s[i] === s[i+1]) { // this is a 2 letter palindrome
            l = getsize(s, i, i+1);
        }
        if (i+2 < s.length && s[i] === s[i+2]) { // 3 letter palindrome
            l = getsize(s, i+1, i+1);
        }
        if (l > longest) { longest = l; }
    }
    return longest;
}

Ini pasti bisa dibersihkan dan dioptimalkan sedikit lebih banyak, tetapi harus memiliki kinerja yang cukup baik di semua skenario kecuali kasus terburuk (serangkaian huruf yang sama).

swilliams
sumber
1
Awalnya saya mengira OP algo # 1 adalah waktu O (n ^ 2), tetapi sebenarnya ini sangat rumit O (n ^ 3), jadi meskipun algoritme Anda tidak berhasil mencapai batas O (n) yang dapat dicapai, itu masih perbaikan.
j_random_hacker
1
Anda menyebutnya "langsung" tetapi penuh i j l s ifdan pemeliharaan status. multi poin pengembalian, kasus tepi ...
v.oddou
1

Hai, Ini kode saya untuk menemukan palindrome terpanjang dalam string. Silakan merujuk ke tautan berikut untuk memahami algoritme http://stevekrenzel.com/articles/longest-palnidrome

Data uji yang digunakan adalah HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE

 //Function GetPalindromeString

public static string GetPalindromeString(string theInputString)
 { 

        int j = 0;
        int k = 0;
        string aPalindrome = string.Empty;
        string aLongestPalindrome = string.Empty ;          
        for (int i = 1; i < theInputString.Length; i++)
        {
            k = i + 1;
            j = i - 1;
            while (j >= 0 && k < theInputString.Length)
            {
                if (theInputString[j] != theInputString[k])
                {
                    break;
                }
                else
                {
                    j--;
                    k++;
                }
                aPalindrome = theInputString.Substring(j + 1, k - j - 1);
                if (aPalindrome.Length > aLongestPalindrome.Length)
                {
                    aLongestPalindrome = aPalindrome;
                }
            }
        }
        return aLongestPalindrome;     
  }
Mohit Bhandari
sumber
Saya tidak yakin apakah ini berfungsi dengan palindrome dengan panjang yang sama ... bisakah Anda mengonfirmasi?
st0le
Ini berfungsi bahkan untuk palindrom Anda dapat menjalankan program ini dan memberi tahu saya jika tidak berhasil untuk Anda.Untuk memahami algoritme, silakan merujuk ke tautan berikut stevekrenzel.com/articles/longest-palnidrome
Mohit Bhandari
@ st0le: Logika ini tidak akan bekerja bahkan untuk palindrom tetapi dapat disesuaikan bahkan untuk palindrom. Mohon maafkan saya untuk persetujuan sebelumnya. Saya mendapatkan logika dan saya akan memperbaruinya dalam beberapa hari saat dan ketika saya punya waktu.
Mohit Bhandari
tidak pernah membaca komentar Anda sebelumnya sampai hari ini ... Anda tidak memanggil saya terakhir kali .... luangkan waktu Anda, itu hanya observasi.
st0le
2
Awalnya saya mengira OP algo # 1 adalah waktu O (n ^ 2), tetapi sebenarnya ini sangat rumit O (n ^ 3), jadi meskipun algoritme Anda tidak berhasil mencapai batas O (n) yang dapat dicapai, itu masih perbaikan.
j_random_hacker
1

Lihat artikel Wikipedia tentang topik ini. Contoh implementasi Algoritma Java Manacher untuk solusi linier O (n) dari artikel di bawah ini:

import java.util.Arrays; kelas publik ManachersAlgorithm {string statis publik findLongestPalindrome (String s) {if (s == null || s.length () == 0) return "";

char[] s2 = addBoundaries(s.toCharArray());
int[] p = new int[s2.length]; 
int c = 0, r = 0; // Here the first element in s2 has been processed.
int m = 0, n = 0; // The walking indices to compare if two elements are the same
for (int i = 1; i<s2.length; i++) {
  if (i>r) {
    p[i] = 0; m = i-1; n = i+1;
  } else {
    int i2 = c*2-i;
    if (p[i2]<(r-i)) {
      p[i] = p[i2];
      m = -1; // This signals bypassing the while loop below. 
    } else {
      p[i] = r-i;
      n = r+1; m = i*2-n;
    }
  }
  while (m>=0 && n<s2.length && s2[m]==s2[n]) {
    p[i]++; m--; n++;
  }
  if ((i+p[i])>r) {
    c = i; r = i+p[i];
  }
}
int len = 0; c = 0;
for (int i = 1; i<s2.length; i++) {
  if (len<p[i]) {
    len = p[i]; c = i;
  }
}
char[] ss = Arrays.copyOfRange(s2, c-len, c+len+1);
return String.valueOf(removeBoundaries(ss));   }
private static char[] addBoundaries(char[] cs) {
if (cs==null || cs.length==0)
  return "||".toCharArray();

char[] cs2 = new char[cs.length*2+1];
for (int i = 0; i<(cs2.length-1); i = i+2) {
  cs2[i] = '|';
  cs2[i+1] = cs[i/2];
}
cs2[cs2.length-1] = '|';
return cs2;   }
private static char[] removeBoundaries(char[] cs) {
if (cs==null || cs.length<3)
  return "".toCharArray();

char[] cs2 = new char[(cs.length-1)/2];
for (int i = 0; i<cs2.length; i++) {
  cs2[i] = cs[i*2+1];
}
return cs2;   }     }

1

RegexpSolusi efisien yang menghindari kekerasan

Dimulai dengan seluruh panjang string dan bekerja ke bawah hingga 2 karakter, ada segera setelah kecocokan dibuat

Untuk "abaccddccefe"regexp menguji 7 pertandingan sebelum kembali ccddcc.

(.) (.) (.) (.) (.) (.) (\ 6) (\ 5) (\ 4) (\ 3) (\ 2) (\ 1)
(.) (.) (. ) (.) (.) (.) (\ 5) (\ 4) (\ 3) (\ 2) (\ 1)
(.) (.) (.) (.) (.) (\ 5) ( \ 4) (\ 3) (\ 2) (\ 1)
(.) (.) (.) (.) (.) (\ 4) (\ 3) (\ 2) (\ 1)
(.) ( .) (.) (.) (\ 4) (\ 3) (\ 2) (\ 1)
(.) (.) (.) (.) (\ 3) (\ 2) (\ 1)
(. ) (.) (.) (\ 3) (\ 2) (\ 1)

Dim strTest
wscript.echo Palindrome("abaccddccefe")

Sub Test()
Dim strTest
MsgBox Palindrome("abaccddccefe")
End Sub

fungsi

Function Palindrome(strIn)

Set objRegex = CreateObject("vbscript.regexp")

For lngCnt1 = Len(strIn) To 2 Step -1
    lngCnt = lngCnt1 \ 2
    strPal = vbNullString

    For lngCnt2 = lngCnt To 1 Step -1
        strPal = strPal & "(\" & lngCnt2 & ")"
    Next

    If lngCnt1 Mod 2 = 1 Then strPal = "(.)" & strPal

    With objRegex
        .Pattern = Replace(Space(lngCnt), Chr(32), "(.)") & strPal
        If .Test(strIn) Then
            Palindrome = .Execute(strIn)(0)
            Exit For
        End If
    End With
Next

End Function

@DickKusleika bisakah Anda memperbarui komentar saya di dailydoseofexcel.com/archives/2016/01/14/… dengan kode yang direvisi di atas. Thx
brettdj

1
public static void main(String[] args) {
         System.out.println(longestPalindromeString("9912333321456")); 
}

    static public String intermediatePalindrome(String s, int left, int right) {
        if (left > right) return null;
        while (left >= 0 && right < s.length()
                && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        return s.substring(left + 1, right);
    }


    public static String longestPalindromeString(String s) {
        if (s == null) return null;
        String longest = s.substring(0, 1);
        for (int i = 0; i < s.length() - 1; i++) {
            //odd cases like 121
            String palindrome = intermediatePalindrome(s, i, i);
            if (palindrome.length() > longest.length()) {
                longest = palindrome;
            }
            //even cases like 1221
            palindrome = intermediatePalindrome(s, i, i + 1);
            if (palindrome.length() > longest.length()) {
                longest = palindrome;
            }
        }
        return longest;
    }

0

Coba string - "HYTBCABADEFGHABCDEDCBAGHTFYW123456789987654321ZWETYGDE"; Ini harus bekerja untuk teman genap dan ganjil. Terima kasih banyak untuk Mohit!

menggunakan namespace std;

string largestPal(string input_str)
{
  string isPal = "";
  string largest = "";
  int j, k;
  for(int i = 0; i < input_str.length() - 1; ++i)
    {
      k = i + 1;
      j = i - 1;

      // starting a new interation                                                      
      // check to see if even pal                                                       
      if(j >= 0 && k < input_str.length()) {
        if(input_str[i] == input_str[j])
          j--;
        else if(input_str[i] == input_str[j]) {
          k++;
        }
      }
      while(j >= 0 && k < input_str.length())
        {
          if(input_str[j] != input_str[k])
            break;
          else
            {
              j--;
              k++;
            }
          isPal = input_str.substr(j + 1, k - j - 1);
            if(isPal.length() > largest.length()) {
              largest = isPal;
            }
        }
    }
  return largest;
}

2
Ini hampir melakukan hal-hal dalam waktu O (n ^ 2). Mengapa membangun isPal- operasi O (n) - hanya untuk mengukur panjangnya !? Juga memiliki upaya buggy dalam menangani bahkan palindrome. Pada bugginess palindrom genap: else if(input_str[i] == input_str[j])tidak akan pernah berhasil karena pengujian yang sama pasti gagal dalam ifpernyataan sebelumnya ; dan bagaimanapun juga itu buggy karena Anda tidak dapat membedakan hanya dengan melihat 2 karakter yang berjarak 2 posisi terpisah apakah Anda sedang melihat palindrom genap atau yang ganjil (pertimbangkan AAAdan AAAA).
j_random_hacker

0

Kode berikut menghitung Palidrom untuk string dengan panjang genap dan panjang ganjil.

Bukan solusi terbaik tetapi berfungsi untuk kedua kasus

HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE HYTBCABADEFGHABCDEDCBAGHTFYW1234567887654321ZWETYGDE

private static String getLongestPalindrome(String string) {
    String odd = getLongestPalindromeOdd(string);
    String even = getLongestPalindromeEven(string);
    return (odd.length() > even.length() ? odd : even);
}

public static String getLongestPalindromeOdd(final String input) {
    int rightIndex = 0, leftIndex = 0;
    String currentPalindrome = "", longestPalindrome = "";
    for (int centerIndex = 1; centerIndex < input.length() - 1; centerIndex++) {
        leftIndex = centerIndex;
        rightIndex = centerIndex + 1;
        while (leftIndex >= 0 && rightIndex < input.length()) {
            if (input.charAt(leftIndex) != input.charAt(rightIndex)) {
                break;
            }
            currentPalindrome = input.substring(leftIndex, rightIndex + 1);
            longestPalindrome = currentPalindrome.length() > longestPalindrome
                    .length() ? currentPalindrome : longestPalindrome;
            leftIndex--;
            rightIndex++;
        }
    }
    return longestPalindrome;
}

public static String getLongestPalindromeEven(final String input) {
    int rightIndex = 0, leftIndex = 0;
    String currentPalindrome = "", longestPalindrome = "";
    for (int centerIndex = 1; centerIndex < input.length() - 1; centerIndex++) {
        leftIndex = centerIndex - 1;
        rightIndex = centerIndex + 1;
        while (leftIndex >= 0 && rightIndex < input.length()) {
            if (input.charAt(leftIndex) != input.charAt(rightIndex)) {
                break;
            }
            currentPalindrome = input.substring(leftIndex, rightIndex + 1);
            longestPalindrome = currentPalindrome.length() > longestPalindrome
                    .length() ? currentPalindrome : longestPalindrome;
            leftIndex--;
            rightIndex++;
        }
    }
    return longestPalindrome;
}

0
  1. Ubah string untuk memisahkan setiap karakter menggunakan pemisah [ini untuk menggabungkan palindrom ganjil dan genap]
  2. Temukan palindrom di sekitar setiap karakter yang memperlakukannya sebagai pusat

Kita dapat menemukan semua palindrom dengan panjang semua menggunakan ini.

Sampel :

kata = abcdcbc

modifiedString = a # b # c # d # c # b # c

palinCount = 1010105010301

panjang palindrom terpanjang = 5;

palindrom terpanjang = bcdcb

kelas publik MyLongestPalindrome {

static String word;
static int wordlength;
static int highestcount = 0;
static int newlength;
static char[] modifiedString; // stores modified string
static int[] palinCount; // stores palindrome length at each position
static char pound = '#';

public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    System.out.println("Enter String : ");
    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader bfr = new BufferedReader(isr);
    word = bfr.readLine();
    wordlength = word.length();
    newlength = (wordlength * 2) - 1;
    convert();
    findpalindrome();
    display();
}

// Inserting # in string
public static void convert() {

    modifiedString = new char[newlength];
    int j = 0;
    int i;
    for (i = 0; i < wordlength - 1; i++) {
        modifiedString[j++] = word.charAt(i);
        modifiedString[j++] = pound;
    }
    modifiedString[j] = word.charAt(i);
}

// display all palindromes of highest length
public static void display() {
    String palindrome;
    String s = new String(modifiedString);
    System.out.println("Length of longest palindrome = " + highestcount);
    for (int i = 0; i < newlength; i++) {
        if (palinCount[i] == highestcount) {
            palindrome = s.substring(i - (highestcount - 1), i
                    + (highestcount));
            i = i + (highestcount - 1);
            palindrome = palindrome.replace("#", "");
            System.out.println(palindrome);
        }
    }
}

// populate palinCount with length of palindrome string at each position
public static void findpalindrome() {
    int left, right, count;
    palinCount = new int[newlength];
    palinCount[0] = 1;
    palinCount[newlength - 1] = 1;
    for (int i = 1; i < newlength - 1; i++) {
        count = 0;
        left = i - 1;
        right = i + 1;
        ;
        if (modifiedString[i] != pound)
            count++;
        while (left >= 0 && right < newlength) {
            if (modifiedString[left] == modifiedString[right]) {
                if (modifiedString[left] != pound)
                    count = count + 2;
                left--;
                right++;
            } else
                break;
        }

        palinCount[i] = count;
        highestcount = count > highestcount ? count : highestcount;

    }

}

}

nnc
sumber
0

Ini akan mengembalikan string palindrom terpanjang dari string yang diberikan

-(BOOL)isPalindromString:(NSString *)strInput
{
    if(strInput.length<=1){
        return NO;
    }
    int halfLenth = (int)strInput.length/2;

    BOOL isPalindrom = YES;
    for(NSInteger i=0; i<halfLenth; i++){

        char a = [strInput characterAtIndex:i];
        char b = [strInput characterAtIndex:(strInput.length-1)-i];

        if(a != b){
            isPalindrom = NO;
            break;
        }
    }
    NSLog(@"-%@- IS Plaindrom %@",strInput,(isPalindrom ? @"YES" : @"NO"));
    return isPalindrom;
}


-(NSString *)longestPalindrom:(NSString *)strInput
{
    if(strInput.length<=1){
        return @"";
    }

    NSString *strMaxPalindrom = @"";

    for(int i = 0; i<strInput.length ; i++){

        for(int j = i; j<strInput.length ; j++){

            NSString *strSub = [strInput substringWithRange:NSMakeRange(i, strInput.length-j)];

            if([self isPalindromString:strSub]){

                if(strSub.length>strMaxPalindrom.length){

                    strMaxPalindrom = strSub;
                }
            }
        }
    }
    NSLog(@"-Max - %@",strMaxPalindrom);
    return strMaxPalindrom;
}

-(void)test
{
    [self longestPalindrom:@"abcccbadeed"];
}

== OUTPUT ===

Masukan: abcccde Keluaran: ccc

Masukan: abcccbd Keluaran: bcccb

Masukan: abedccde Keluaran: edccde

Masukan: abcccdeed Output: akta

Masukan: abcccbadeed Keluaran: abcccba

Kiran Patel
sumber
0

Berikut implementasinya dalam javascript:

var longestPalindromeLength = 0;
var longestPalindrome = ''

function isThisAPalidrome(word){
  var reverse = word.split('').reverse().join('')
  return word == reverse
}

function findTheLongest(word){ // takes a word of your choice
  for(var i = 0; i < word.length; i++){ // iterates over each character
    var wordMinusOneFromBeginning = word.substr(i, word.length) // for each letter, create the word minus the first char
    for(var j = wordMinusOneFromBeginning.length; j > 0; j--){ // for the length of the word minus the first char
      var wordMinusOneFromEnding = wordMinusOneFromBeginning.substr(0, j) // create a word minus the end character
      if(wordMinusOneFromEnding <= 0) // make sure the value is more that 0,
      continue // if more than zero, proced to next if statement
      if(isThisAPalidrome(wordMinusOneFromEnding)){ // check if the word minus the first character, minus the last character = a plaindorme
        if(wordMinusOneFromEnding.length > longestPalindromeLength){ // if it is
          longestPalindromeLength = wordMinusOneFromEnding.length; // save its length
          longestPalindrome = wordMinusOneFromEnding // and save the string itself
        } // exit the statement that updates the longest palidrome
      } // exit the stament that checks for a palidrome
    } // exit the loop that goes backwards and takes a letter off the ending
  } // exit the loop that goes forward and takes off the beginning letter
  return console.log('heres the longest string: ' + longestPalindrome
  + ' its ' + longestPalindromeLength + ' charachters in length'); // return the longest palidrome! :)
}
findTheLongest('bananas');

alex bennett
sumber
Tidak tahu mengapa ini tidak disukai - berfungsi seperti pesona. Membawa saya melalui wawancara dengan teknologi CA dengan baik.
alex bennett
0

Untuk solusi linier, Anda dapat menggunakan algoritma Manacher. Ada algoritma lain yang disebut Algoritma Gusfield, dan di bawah ini adalah kode di java:

public class Solution {  
    char[] temp;   
    public int match(int a, int b,int len){   
        int i = 0;   
        while (a-i>=0 && b+i<len && temp[a-i] == temp[b+i]) i++;   
        return i;   
    }  

    public String longestPalindrome(String s) {  

        //This makes use of the assumption that the string has not more than 1000 characters.  
        temp=new char[1001*2];  
        int[] z=new int[1001 * 2];  
        int L=0, R=0;  
        int len=s.length();  

        for(int i=0;i<len*2+1;i++){  
            temp[i]='.';  
        }  

        for(int i=0;i<len;++i){  
            temp[i*2+1] = s.charAt(i);  
        }  

        z[0]=1;  
        len=len*2+1;  

        for(int i=0;i<len;i++){  
            int ii = L - (i - L);     
            int n = R + 1 - i;  
            if (i > R)  
            {  
                z[i] = match(i, i,len);  
                L = i;  
                R = i + z[i] - 1;  
            }  
            else if (z[ii] == n)  
            {  
                z[i] = n + match(i-n, i+n,len);  
                L = i;  
                R = i + z[i] - 1;  
            }  
            else  
            {  
                z[i] = (z[ii]<= n)? z[ii]:n;  
            }   
        }  

        int n = 0, p = 0;  
        for (int i=0; i<len; ++i)  
            if (z[i] > n)  
                n = z[p = i];  

        StringBuilder result=new StringBuilder();  
        for (int i=p-z[p]+1; i<=p+z[p]-1; ++i)  
            if(temp[i]!='.')  
                result.append(String.valueOf(temp[i]));  

        return result.toString();  
    }  
}  

Anda dapat menemukan lebih banyak tentang solusi lain seperti solusi O (n ^ 2) terbaik atau algoritma Manacher dari blog saya sendiri .

traceformula
sumber
0

Di sini saya telah menulis logika mencobanya :)

public class palindromeClass{

public  static String longestPalindromeString(String in) {
        char[] input = in.toCharArray();
        int longestPalindromeStart = 0;
        int longestPalindromeEnd = 0;

        for (int mid = 0; mid < input.length; mid++) {
            // for odd palindrome case like 14341, 3 will be the mid
            int left = mid-1;
            int right = mid+1;
            // we need to move in the left and right side by 1 place till they reach the end
            while (left >= 0 && right < input.length) {
                // below check to find out if its a palindrome
                if (input[left] == input[right]) {
                    // update global indexes only if this is the longest one till now
                    if (right - left > longestPalindromeEnd
                            - longestPalindromeStart) {
                        longestPalindromeStart = left;
                        longestPalindromeEnd = right;
                    }
                }
                else
                    break;
                left--;
                right++;
            }
            // for even palindrome, we need to have similar logic with mid size 2
            // for that we will start right from one extra place
            left = mid;
            right = mid + 1;// for example 12333321 when we choose 33 as mid
            while (left >= 0 && right < input.length)
            {
                if (input[left] == input[right]) {
                    if (right - left > longestPalindromeEnd
                            - longestPalindromeStart) {
                        longestPalindromeStart = left;
                        longestPalindromeEnd = right;
                    }
                }
                else
                    break;
                left--;
                right++;
            }


        }
        // we have the start and end indexes for longest palindrome now
        return in.substring(longestPalindromeStart, longestPalindromeEnd + 1);
    }
public static void main(String args[]){
System.out.println(longestPalindromeString("HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE"));
}

}
dingin
sumber
ini memberikan semua palindrom dalam string tidak hanya yang terpanjang
Vivek Mishra
0

Solusi ini memiliki kompleksitas O (n ^ 2). O (1) adalah kompleksitas ruang.

public class longestPalindromeInAString {

        public static void main(String[] args) {
            String a =  "xyMADAMpRACECARwl"; 
            String res = "";
            //String longest = a.substring(0,1);
            //System.out.println("longest => " +longest);
            for (int i = 0; i < a.length(); i++) {
                String temp = helper(a,i,i);//even palindrome
                if(temp.length() > res.length()) {res = temp ;}
                temp = helper(a,i,i+1);// odd length palindrome
                if(temp.length() > res.length()) { res = temp ;}

            }//for
            System.out.println(res);
            System.out.println("length of " + res + " is " + res.length());

        }

        private static String helper(String a, int left, int right) {
            while(left>= 0 && right <= a.length() -1  &&  a.charAt(left) == a.charAt(right)) {
                left-- ;right++ ;
            }
            String curr = a.substring(left + 1 , right);
            System.out.println("curr =>" +curr);
            return curr ;
        }

    }
Soudipta Dutta
sumber
0

#longest palindrome
s='HYTBCABADEFGHABCDEDCBAGHTFYW123456789987654321ZWETYGDE'
out1=[]
def substring(x):
    for i in range(len(x)):
        a=x[i:]
        b=x[:-i]
        out1.append(a)
        out1.append(b)
        
    return out1

for i in range(len(s)):
    substring(s[i:])    
final=set([item for item in out1 if len(item)>2])
final
palind={item:len(item) for item in final if item==item[::-1]}
print(palind)
sorted(palind.items(),reverse=True, key=lambda x: x[1])[0]

{'DED': 3, '123456789987654321': 18, '67899876': 8, 'ABCDEDCBA': 9, '456789987654': 12, '34567899876543': 14, 'BCDEDCB': 7, 'ABA': 3, ' 5678998765 ': 10,' 2345678998765432 ': 16,' CDEDC ': 5,' 789987 ': 6,' 8998 ': 4} (' 123456789987654321 ', 18)

ashish bansal
sumber
-1

Inilah algoritma saya:

1) atur pusat saat ini menjadi huruf pertama

2) secara bersamaan berkembang ke kiri dan kanan sampai Anda menemukan palindrom maksimum di sekitar pusat saat ini

3) jika palindrome yang Anda temukan lebih besar dari palindrome sebelumnya, perbarui

4) atur pusat saat ini menjadi huruf berikutnya

5) ulangi langkah 2) sampai 4) untuk semua huruf dalam string

Ini berjalan di O (n).

Semoga membantu.

laba-laba
sumber
5
Pertimbangkan string "aaaaaa". Ini berjalan di O (n ^ 2) menggunakan algoritme Anda.
paislee
1
Awalnya saya mengira OP algo # 1 adalah waktu O (n ^ 2), tetapi sebenarnya ini sangat rumit O (n ^ 3), jadi meskipun algoritme Anda tidak berhasil mencapai batas O (n) yang dapat dicapai, itu masih perbaikan.
j_random_hacker
Itulah solusi perluasan N2 klasik. TAPI, Sebenarnya itu mendekati solusi Manacher seperti yang dijelaskan dalam video ini: youtube.com/watch?v=V-sEwsca1ak perbedaannya adalah poin 4. Manacher menggunakan kembali informasi untuk menghindari pemindaian ulang surat yang sudah dipindai.
v.oddou
-2

Referensi: Wikipedia.com

Algoritme terbaik yang pernah saya temukan, dengan kompleksitas O (N)

 import java.util.Arrays;

 public class ManachersAlgorithm {

  public static String findLongestPalindrome(String s) {
    if (s==null || s.length()==0)
      return "";

    char[] s2 = addBoundaries(s.toCharArray());
    int[] p = new int[s2.length]; 
    int c = 0, r = 0; // Here the first element in s2 has been processed.
    int m = 0, n = 0; // The walking indices to compare if two elements are the same
    for (int i = 1; i<s2.length; i++) {
      if (i>r) {
        p[i] = 0; m = i-1; n = i+1;
      } else {
        int i2 = c*2-i;
        if (p[i2]<(r-i)) {
          p[i] = p[i2];
          m = -1; // This signals bypassing the while loop below. 
        } else {
          p[i] = r-i;
          n = r+1; m = i*2-n;
        }
      }
      while (m>=0 && n<s2.length && s2[m]==s2[n]) {
        p[i]++; m--; n++;
      }
      if ((i+p[i])>r) {
        c = i; r = i+p[i];
      }
    }
    int len = 0; c = 0;
    for (int i = 1; i<s2.length; i++) {
      if (len<p[i]) {
        len = p[i]; c = i;
      }
    }
    char[] ss = Arrays.copyOfRange(s2, c-len, c+len+1);
    return String.valueOf(removeBoundaries(ss));
  }

  private static char[] addBoundaries(char[] cs) {
    if (cs==null || cs.length==0)
      return "||".toCharArray();

    char[] cs2 = new char[cs.length*2+1];
    for (int i = 0; i<(cs2.length-1); i = i+2) {
      cs2[i] = '|';
      cs2[i+1] = cs[i/2];
    }
    cs2[cs2.length-1] = '|';
    return cs2;
  }

  private static char[] removeBoundaries(char[] cs) {
    if (cs==null || cs.length<3)
      return "".toCharArray();

    char[] cs2 = new char[(cs.length-1)/2];
    for (int i = 0; i<cs2.length; i++) {
      cs2[i] = cs[i*2+1];
    }
    return cs2;
  }    
}
Sazzad Hissain Khan
sumber
-5

solusi saya adalah:

static string GetPolyndrom(string str)
{
    string Longest = "";

    for (int i = 0; i < str.Length; i++)
    {
        if ((str.Length - 1 - i) < Longest.Length)
        {
            break;
        }
        for (int j = str.Length - 1; j > i; j--)
        {
            string str2 = str.Substring(i, j - i + 1);
            if (str2.Length > Longest.Length)
            {
                if (str2 == str2.Reverse())
                {
                    Longest = str2;
                }
            }
            else
            {
                break;
            }
        }

    }
    return Longest;
}
Tomer keisar
sumber
1
Ini membutuhkan waktu kubik dalam panjang string, karena operasi Substring()dan string-equality ( ==). Ini pada dasarnya identik dengan OP's algo # 1.
j_random_hacker