我将从一个例子开始;给定n = 1且m = 100且列表为[1,2,3] 产生1位数和2位数的所有数字,依此类推但在这种情况下它们需要小于100。
输出:
- 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33
然后我们停下来,因为接下来的数字将超过100,例如:
- 111, 112, 113, 121, 122, 123, 131, 132, 133, 21..,. 22..., 23..., 31, 32, 33
正如您所注意到我将1, 2, 3, 4
附加到之前创建的数字上,为此我使用递归函数,该函数在列表中的每个数字的for循环中启动,并且它们一直运行到生成的数字大于我的限制。
def x(str, finish, d, c)
return if d >= finish
[1, 2, 3, 4].each do |e|
x(str, end, d*c+e)
end
# do something if d >= str
end
如果我需要从1开始,这可以正常工作,但如果我的起始数字要大得多,我仍然需要开始创建这个序列。
有人可以帮我解决一个产生相同序列的解决方案,但是从任何起点而不是1,所以如果例如起点是100而结束200那么输出将是:
111, 112, 113, 114, 121, 122, 123, 124, 131, 132, 132 [...]
任何编程语言的解决方案都不错,但请不要内置核心库。
答案 0 :(得分:4)
<强>代码强>
minimum = 78
maximum = 3332
list = [3, 4, 5, 6, 7]
generate_em(minimum, maximum, list)
#=> [333, 334, 335, 336, 337, 343, 344, 345, 346, 347, 353, 354, 355, 356,
# 357, 363, 364, 365, 366, 367, 373, 374, 375, 376, 377, 433, 434, 435,
# 436, 437, 443, 444, 445, 446, 447, 453, 454, 455, 456, 457, 463, 464,
# 465, 466, 467, 473, 474, 475, 476, 477, 533, 534, 535, 536, 537, 543,
# 544, 545, 546, 547, 553, 554, 555, 556, 557, 563, 564, 565, 566, 567,
# 573, 574, 575, 576, 577, 633, 634, 635, 636, 637, 643, 644, 645, 646,
# 647, 653, 654, 655, 656, 657, 663, 664, 665, 666, 667, 673, 674, 675,
# 676, 677, 733, 734, 735, 736, 737, 743, 744, 745, 746, 747, 753, 754,
# 755, 756, 757, 763, 764, 765, 766, 767, 773, 774, 775, 776, 777]
<强>实施例强>
#1
minimum = 0
maximum = 100
list = [0, 1, 2]
generate_em(minimum, maximum, list)
#=> [0, 1, 2, 10, 11, 12, 20, 21, 22, 100]
#2
digits_min = minimum.to_s.size
#=> 1
#3
digits_min
<强>解释强>
示例#1
上述第一个例子的步骤如下:
mimimum
如果digits_min
大于list
的最大digits_min += 1 if minimum > (list.max.to_s*digits_min).to_i
digits_min
#=> 1
digits_max = maximum.to_s.size
#=> 3
位数,请将digits_max
增加一。
maximum
如果digits_max
小于list
中的最小digits_max -= 1 if maximum < (list.min.to_s*digits_max).to_i
digits_max
#=> 2
位数,请将digits_max
减1。
3
我们将2
从c = digits_min..digits_max
#=> 1..2
d = c.each_with_object([])
#=> #<Enumerator: 1..2:each_with_object([])>
缩减为d.entries
#=> [[1, []], [2, []]]
n, arr = d.next
#=> [1, []]
n #=> 1
arr
#=> []
e = list.permutation(n)
#=> #<Enumerator: [1, 2, 3]:permutation(2)>
f = e.to_a
#=> [[1], [2], [3]]
arr.concat f
#=> [[1], [2], [3]]
n, arr = d.next
#=> [2, [[1], [2], [3]]]
n #=> 2
arr
#=> [[1], [2], [3]]
e = list.permutation(n)
#=> #<Enumerator: [1, 2, 3]:permutation(2)>
f = e.to_a
#=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
arr.concat f
#=> [[1], [2], [3], [1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
arr
我们可以通过在其上调用Enumerable#entries(或Enumerable#to_a)来查看此枚举器生成的元素。
each_with_object
g = arr.map { |a| a.join.to_i }
#=> [1, 2, 3, 12, 13, 21, 23, 31, 32]
h = g.uniq
#=> [1, 2, 3, 12, 13, 21, 23, 31, 32]
h.select { |n| (minimum..maximum).cover?(n) }
#=> [1, 2, 3, 12, 13, 21, 23, 31, 32]
由78 > (list.max.to_s*2).to_i
#=> 78 > 77 => true
块返回。
3332 < (list.min.to_s*4).to_i
#=> 3332 < 3333 => true
示例#2
在第二个示例中,没有生成两位数的组合,因为
uniq
并且没有生成四位数组合,因为
[0, 1, 2, 0, 1, 2, 10, 11, 12, 20, 21, 22, 0, 1, 2, 10, 11, 12, 20, 21, 22, 100]
示例#3
如果没有console.log(new Date().toUTCString());
,该方法将返回重复值:
var value = new Date().toISOString();
答案 1 :(得分:3)
由于您在Ruby中编写了示例代码,因此可以使用repeated_permutation
:
def possible_numbers(arr, min, max)
min_digits = min.to_s.size
max_digits = max.to_s.size
(min_digits..max_digits).flat_map do |i|
arr.repeated_permutation(i)
.map { |digits| digits.join.to_i }
.select { |number| number >= min && number <= max }
.uniq
end
end
p possible_numbers([1, 2, 3], 100, 200)
# => [111, 112, 113, 121, 122, 123, 131, 132, 133]
答案 2 :(得分:2)
因此,这需要输入所提供的数字,重复所有数字组合,直到达到最大值。您将要调整它们以包括在输入非整数的情况下的恢复和保存,或者由于某种原因否则无法达到最大值 - 但这是一个可靠的框架。
digits = [1,2,3]
max = 100
def possible_numbers(arr, max)
loop do
arr.product(arr).each do |combo|
return arr.uniq if combo.join("").to_i > max
arr << combo.join("").to_i
end
end
end
possible_numbers(digits, max)
输出:
=> [1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33]
答案 3 :(得分:1)
您可以从“正确”(最低位数)前进到“左侧”(最高位数),跟踪两个值:
min
,与您目前处理的数字位数相同的最小有效整数。因此,例如,如果您处理了尾随27
,则最不有效的两位数整数为11
。max
,与您目前处理的和具有相同位数的最小有效整数大于或等于您目前处理的位数。因此,例如,如果您处理了尾随27
,则大于或等于27
的最小有效两位数整数为31
。
max
并不总是存在。例如,没有大于或等于70
的有效两位数整数。您需要min
的原因是,如果您遇到的数字不在您允许的数字列表中,那么新的max
将包含之前的min
而不是之前的max
{1}}。 (例如,大于或等于02
的最小有效两位数整数为11
,而不是12
。)
最后,如果存在,则返回max
;否则,您返回min
,但在列表中添加最少数字。
例如,如果this.allowedDigits
是允许数字的集合,那么我们可以写(用Java):
private Integer getAllowedDigitGreaterThanOrEqualTo(final int digit) {
for (int result = digit; result < 10; ++result) {
if (this.allowedDigits.contains(result)) {
return result;
}
}
// digit is bigger than anything in the list:
return null;
}
private int getAllowedNumberGreaterThanOrEqualTo(int n) {
int minResult = 0;
Integer maxResult = 0;
int powerOfTen = 1;
while (n > 0) {
final int digit = n % 10;
n /= 10;
minResult = getAllowedDigitGreaterThanOrEqualTo(0) * powerOfTen + minResult;
if (maxResult != null && this.allowedDigits.contains(digit)) {
maxResult = digit * powerOfTen + maxResult;
} else {
final Integer newDigit = getAllowedDigitGreaterThanOrEqualTo(digit + 1);
if (newDigit == null) {
maxResult = null;
} else {
maxResult = newDigit * powerOfTen + minResult;
}
}
powerOfTen *= 10;
}
if (maxResult == null) {
return getAllowedDigitGreaterThanOrEqualTo(1) * powerOfTen + minResult;
} else {
return maxResult;
}
}