庞果网回文数问题ruby解答

题目地址:http://hero.pongo.cn/Question/Details?ID=72&ExamID=70

题目详情

回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。


输入:非空仅由小写字母组成的字符串,长度不超过100;

输出:能组成的所有回文串的个数(因为结果可能非常大,输出对1000000007取余数的结果)。


例如:输入"aabb" 输出为2(因为“aabb”对应的所有回文字符串有2个:abba和baab)



这个问题的解决首先要将回文数问题转变为一般的排列组合问题,如果直接套排列组合公式又太过于简单,因此,写了一个arrange_count 来递归的处理排列问题。

一个回文数,要满足,所有的字母的个数奇数个的字母个数不能超过2,否则不能够组成回文数。:个数为0或者为1时,那么这个奇数个数字的字母本身对于最终结果不能起到任何作用; 个数为2时,可以两者变换位置,则会造成多两种状态。


(代码中没有除以一个固定的数)


class Palindrome
  def initialize(pal)
    @pal = pal.chars.to_a
  end

  def count
    chars = []
    odd_count = 0
    @pal.uniq.each do |char|
      char_count = @pal.count(char)
      odd_count += 1 if char_count.odd?
      chars.concat (char*(char_count/2)).chars.to_a
    end
    arrange_count(chars) * odd_process(odd_count)
    rescue
      return 0
  end

  private
  def arrange_count(array)
    return 1 if array.count == 1
    count = 0
    array.each_index do |i|
      tmp_array = array.dup
      tmp_array.delete_at(i)
      count += arrange_count(tmp_array)
    end
    count
  end
  
  def odd_process(odd_count)
    h = { 0 => 1, 1 => 1, 2 => 2}
    ret = h[odd_count]
    raise if ret.nil?
    ret 
  end
end

describe Palindrome do
  it "should return 2 if input is aabb " do
    Palindrome.new("aabb").count.should == 2
  end
  
  it "should return 0 if input is not a palindrome" do 
    Palindrome.new("abc").count.should == 0
  end

  it "should return 24 if input is abcddcba " do 
    Palindrome.new("abcddcba").count.should == 24
  end

  it "should return 6 if input is abcfcba " do 
    Palindrome.new("abcfcba").count.should == 6
  end

  it "should return if input is abbccc" do 
    Palindrome.new("abbccc").count.should == 4
  end

end


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值