2011-07-27 47 views
5

tôi đang cố gắng để có một chuỗi, giữa chiều dài 1 đến 10, và đầu ra tất cả các cách có thể phá vỡ chuỗi thành chuỗi con liên tiếp có kích thước 1, 2, hoặc 3. Ví dụ:Làm thế nào để tách một chuỗi thành các chuỗi liên tiếp có chiều dài tối đa là 3 trong tất cả các cách có thể?

Input: 123456

Cắt số nguyên thành các ký tự riêng lẻ, sau đó tiến hành để tìm các kết hợp. Mã sẽ trả về tất cả các mảng sau.

[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] 

Tôi đang cố gắng thực hiện điều này bằng ruby. Cảm ơn!

+3

Và những gì bạn đã cố gắng cho đến nay? –

+0

Đầu vào cần được chia thành các khối có kích thước tối đa 3. Ví dụ [1234,5,6] sẽ không hoạt động vì mục đầu tiên quá lớn. Tôi đã làm việc trên hoán vị và kết hợp, nhưng không thể tìm ra cách để có được hoán vị chứa các khối có kích thước khác nhau (một số có 1 ký tự, một số có 2 và một số có 3). Tôi cũng đã bắt đầu làm việc trên một cây quyết định, nhưng không nhận được rất xa. – Drizzit12

+1

@Richard: Điều này không liên quan gì đến hoán vị. Một hoán vị là một sắp đặt lại. Bạn đang giữ các con số theo cùng thứ tự. – PengOne

Trả lời

4

Đây là chức năng hoạt động. Có thể không tối ưu vì tôi không dành nhiều thời gian cho nó.

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

CHỈNH SỬA: Làm cho nó ngắn hơn một chút và độ dài hiện được chuyển làm tham số thứ hai để hoạt động linh hoạt.

+0

http://www.ideone.com/cmWCl – Nick

+0

Cảm ơn. Tôi đã cải thiện mã một chút. http://www.ideone.com/uzrnh – RocketR

+0

Tôi khuyên bạn nên sử dụng '.map {... if ...}. compact' cho kiểu. –

3

Tôi mất một thời gian để tìm ra điều này, đó là một vấn đề khó khăn hơn nhiều, sau đó tôi lần đầu tiên mặc dù. Nhưng cuối cùng tôi đã gặp giải pháp này:

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 } 

Tạo:

["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"] 
+0

Đây không phải là đầu ra mà OP là sau. – PengOne

+1

Nó không phải là? Tại sao? Bạn có thể cụ thể hơn không? – Andy

1

Đây là một:

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 

và sau đó

>> "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 
Các vấn đề liên quan