【问题标题】:How to split a string into consecutive substrings of length at most 3 in all possible ways?如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串?
【发布时间】:2011-07-27 21:52:38
【问题描述】:

我正在尝试获取长度在 1 到 10 之间的字符串,并输出将字符串分解为大小为 1、2 或 3 的连续子字符串的所有可能方式。例如:

Input: 123456

将整数切成单个字符,然后继续查找组合。 该代码将返回以下所有数组。

    [1, 2, 3, 4, 5, 6]  
    [12, 3, 4, 5, 6]  
    [1, 23, 4, 5, 6]  
    [1, 2, 34, 5, 6]  
    [1, 2, 3, 45, 6]  
    [1, 2, 3, 4, 56]  
    [12, 34, 5, 6]  
    [12, 3, 45, 6]  
    [12, 3, 4, 56]  
    [1, 23, 45, 6]  
    [1, 2, 34, 56]  
    [1, 23, 4, 56]  
    [12, 34, 56]  
    [123, 4, 5, 6]  
    [1, 234, 5, 6]  
    [1, 2, 345, 6]  
    [1, 2, 3, 456]  
    [123, 456]  
    [1, 23, 456]  
    [1, 234, 56]  
    [12, 345, 6]  
    [12, 3, 456]  
    [123, 4, 56]  
    [123, 45, 6]

我正在尝试在 ruby​​ 中执行此操作。谢谢!

【问题讨论】:

  • 到目前为止你尝试过什么?
  • 输入需要被分解成最大大小为 3 的块。例如 [1234,5,6] 不起作用,因为第一项太大。我一直在研究排列和组合,但不知道如何获得包含不同大小块的排列(有些带有 1 个字符,有些带有 2 个字符,有些带有 3 个字符)。我也开始研究决策树,但还没有走多远。
  • @Richard:这与排列无关。排列是重新排序。您将数字保持在相同的顺序。
  • @Peng -- 你是对的。但我想知道排列是否真的会最终出现在解决方案中,倾斜地......仍在思考,但我已经很晚了......
  • @Andy:绝对不是。他只需要找到断线的位置。这里没有任何东西被置换。他有 9 个位置供 ,s 去,并且想选择它们,以便它们之间最多出现 3 个数字。数字保持有序。

标签: ruby variables


【解决方案1】:

这是一个工作函数。可能不是最佳的,因为我没有花太多时间。

str = "1234567890"

def f(s, n)
    return [[]] if s.empty?

    (1..[n, s.length].min).map{|c| f(s[c..-1], n).map{|a| [s[0, c]] + a}}.inject(&:+)
end

puts f(str, 3).collect{|l| l * "\t"}

编辑:让它更短一些,长度现在作为第二个参数传递以实现灵活性。

【讨论】:

  • 我建议使用.map{... if ...}.compact 来表示样式。
  • 已修复。它看起来真的很神秘 :) Ruby 是一门很棒的语言。
【解决方案2】:

我花了很长时间才弄清楚这一点,但这是一个比我第一次更难的问题。但最终我找到了这个解决方案:

def combinations(s)
  c = (s.length > 3) ? [] : [[s]]
  max = [4, s.length].min
  (1...max).inject(c) do |c, i|
    combinations(s[i..-1]).inject(c) do |c, tail|
      c.push([s[0...i]] + tail)
    end
  end
end

combinations("12345").each { |c| p c }

生产:

["1", "2", "345"]
["1", "2", "3", "45"]
["1", "2", "3", "4", "5"]
["1", "2", "34", "5"]
["1", "23", "45"]
["1", "23", "4", "5"]
["1", "234", "5"]
["12", "345"]
["12", "3", "45"]
["12", "3", "4", "5"]
["12", "34", "5"]
["123", "45"]
["123", "4", "5"]

【讨论】:

  • 这不是 OP 所追求的输出。
  • 不是吗?为什么?你能说得更具体点吗?
【解决方案3】:

这是另一个:

class String
  def splitup(prefix=nil)
    parts = []
    if size <= 3
      parts << [prefix,self].compact * ","
    end
    (1..([size,3].min)).each do |p|
      next if p >= size
      parts << slice(p..-1).splitup([prefix,slice(0,p)].compact * ",")
    end
    parts
  end

  def report
    flat = splitup.flatten.sort_by {|x| [-x.size,x]}
    puts
    puts "#{flat.size} permutations of #{self}"
    puts flat
  end
end

然后

>> "123456".report

24 permutations of 123456
1,2,3,4,5,6
1,2,3,4,56
1,2,3,45,6
1,2,34,5,6
1,23,4,5,6
12,3,4,5,6
1,2,3,456
1,2,34,56
1,2,345,6
1,23,4,56
1,23,45,6
1,234,5,6
12,3,4,56
12,3,45,6
12,34,5,6
123,4,5,6
1,23,456
1,234,56
12,3,456
12,34,56
12,345,6
123,4,56
123,45,6
123,456

【讨论】:

    【解决方案4】:
    def f(s, mx)
      (1..[s.size, mx].min).each_with_object([]) do |n,a|
         if n < s.size
           sf = s[0, n]
           f(s[n..-1], mx).each { |c| a << [sf, *c] }
         else
           a << [s]
         end
      end
    end
    

    f("12345", 3)
      #=> [["1", "2", "3", "4", "5"], ["1", "2", "3", "45"],
      #    ["1", "2", "34", "5"], ["1", "2", "345"], ["1", "23", "4", "5"],
      #    ["1", "23", "45"], ["1", "234", "5"], ["12", "3", "4", "5"],
      #    ["12", "3", "45"], ["12", "34", "5"], ["12", "345"],
      #    ["123", "4", "5"], ["123", "45"]] => [["1", "2", "3", "4"],
      #    ["1", "2", "34"], ["1", "23", "4"], ["1", "234"],
      #    ["12", "3", "4"], ["12", "34"], ["123", "4"]] 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      • 2012-11-20
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      相关资源
      最近更新 更多