Ruby - 查找字符串中最长的回文子串

时间:2014-11-05 23:58:50

标签: ruby string substring reverse palindrome

我理解如何查找一个字符串是否为回文

string1 == string1.reverse

虽然在一个字符串中有多个回文,但它有点困难

"abcdxyzyxabcdaaa"

在上面的字符串中,有4个长度大于1的回文。

"xyzyx", "yzy", "aaa" and "aa"

在这种情况下,最长的回文是" xyxyx",长度为5个字符。

虽然如何解决这个问题。

我知道数组#组合方法,但在这种情况下不会起作用。

我正在考虑实施类似的东西

def longest_palindrome(string)
  palindromes = []
  for i in 2..string.length-1
    string.chars.each_cons(i).each {|x|palindromes.push(x) if x == x.reverse}
  end
  palindromes.map(&:join).max_by(&:length)
end

4 个答案:

答案 0 :(得分:3)

如果您只是寻找最大的回文子串,这是一个快速而肮脏的解决方案。

def longest_palindrome(string, size)
  string.size.times do |start| # loop over the size of the string
    break if start + size > string.size # bounds check

    reverse = string[start, size].reverse

    if string.include? reverse #look for palindrome
      return reverse #return the largest palindrome
    end
  end
  longest_palindrome(string, size - 1) # Palindrome not found, lets look for the next smallest size 
end

答案 1 :(得分:0)

检查整个字符串str是否是回文。如果是的话,我们就完成了;如果没有,请检查所有长度为str.size-1的子字符串。如果一个是回文,我们就完成了;如果没有,请检查长度为str.size-1的子字符串,依此类推。

def longest_palindrome(str)
  arr = str.downcase.chars
  str.length.downto(1) do |n|
    ana = arr.each_cons(n).find { |b| b == b.reverse }
    return ana.join if ana
  end
end

longest_palindrome "abcdxyzyxabcdaaa"
  #=> "xyzyx"
longest_palindrome "abcdefghba"
  #=> "a"

此处的关键方法是Enumerable#each_cons

答案 2 :(得分:0)

def longest_palindrome(string)
  longest = ''
  i = 0
  while i < string.length
    j = 1
    while (i + j) <= string.length
      x = string.slice(i, j)
      if (x == x.reverse) && (x.length > longest.length)
        longest = x
      end
      j += 1
    end
    i += 1
  end
  longest
end

切片方法可以解决这个问题。使用经典的双while循环方法测试每个子字符串,(i, j)分别表示子字符串的起始索引和长度。 string.slice(start_index, substring_length)

String#slice方法的工作方式如下:

"bdehannahc".slice(3, 8) == "hannah" # which is a palindrome and would be 
                                     # found by the method introduced above

答案 3 :(得分:-1)

这是另一种解决方案,使用较少的Ruby和迭代功能而不是递归:

def longest_palindrome(string)
  # to find the longest palindrome, start with whole thing
  substr_start = 0
  substr_length = string.length
  while substr_length > 0 # 1 is a trivial palindrome and the end case
#    puts 'substr_length is:' + substr_length.to_s
    while substr_start <= string.length - substr_length
#      puts 'start is: ' + substr_start.to_s
      if palindrome?(string.slice(substr_start,substr_length))
        puts 'found palindrome: ' + string.slice(substr_start,substr_length)
        return string.slice(substr_start,substr_length)
      end
      substr_start += 1
    end
    substr_start = 0 # inner loop ctr reset
    substr_length -= 1
  end
  puts 'null string tested?'
  return ''
end