我想知道
Ruby中是否有一种优雅的方式来提出一些整数的所有排列(重复),其要求是1)引入的整数必须按从左到右的升序排列2)零不受此规则的约束.
下面,我有三位数的输出子集和整数0,1,2,3,4,5,6,7,8,9.这只是总答案的一个子集,特别是它是以5开头的子集.我已经在其中包含了几个注释.
500 - Zero is used twice
505 - 5 is used twice. Note that 504 is not included because 5 was introduced on the left and 4 < 5
506
507
508
509
550
555
556
557
558
559
560
565 - Though 5 < 6, 5 can be used twice because 5 was introduced to the left of 6.
566
567
568
569
570
575
577
578
579
580
585
588
589
590
595
599
我需要能够以任意长的输出长度(不仅仅是3,像这个例子)来做,我需要能够为特定的整数集做到这一点.但是,零将始终是排序规则不适用的整数.
最佳答案 这可行:
class Foo
include Comparable
attr :digits
def initialize(digits)
@digits = digits.dup
end
def increment(i)
if i == -1 # [9,9] => [1,0,0]
@digits.unshift 1
else
succ = @digits[i] + 1
if succ == 10 # [8,9] => [9,0]
@digits[i] = 0
increment(i-1)
else
@digits[i] = @digits[0,i].sort.detect { |e| e >= succ } || succ
end
end
self
end
def succ
Foo.new(@digits).increment(@digits.length-1)
end
def <=>(other)
@digits <=> other.digits
end
def to_s
digits.join
end
def inspect
to_s
end
end
range = Foo.new([5,0,0])..Foo.new([5,9,9])
range.to_a
#=> [500, 505, 506, 507, 508, 509, 550, 555, 556, 557, 558, 559, 560, 565, 566, 567, 568, 569, 570, 575, 577, 578, 579, 580, 585, 588, 589, 590, 595, 599]
递增数字的主要规则是:
@digits[i] = @digits[0,i].sort.detect { |e| e >= succ } || succ
这会将剩余的数字排序到当前数字(“向左”引入的数字),并检测第一个等于或大于后继数的元素.如果找不到,则使用后继本身.