How do I get a sequence of a g开发者_如何学编程iven number in Groovy, for example:
def number = 169
// need a method in groovy to find the consecutive numbers that is, 1,6,9,16,69,169
// not 19!
There is a method in Groovy called subsequences()
, but that is not doing this job exactly. Can anyone say me how can I do this in Groovier way? Or is there any built-in method?
Run this in the Groovy console
def number = 169
number = number.toString() as List
def results = []
0.upto(number.size()) {numDigits ->
for(int startPos = 0; startPos + numDigits < number.size(); startPos++) {
def result = number[startPos..startPos + numDigits]
results << result.join().toInteger()
}
}
assert results == [1, 6, 9, 16, 69, 169]
Although late to the game, here's a solution that is less sophisticated than @tim's, but also will do the trick:
def str = 169 as String
def result = [] as SortedSet
(0..<str.length()).each { i ->
(i..<str.length()).each { j ->
result << str[i..j].toInteger()
}
}
Edit:
The code works like two nested loops that iterate over the String representation of the number and extracting the various substrings from it.
The outer loop represents the start index of the substring and the inner loop the end index of the substring. The outer loop will go from the beginning to the end of the String, whereas the inner loop starts at the current start index and goes from there to the end.
The as SortedSet
ensures that there are no duplicate numbers in the result and that the numbers are sorted in ascending order.
1 6 9
-----
0 1 2 <-- index
=====
[1]6 9 (i=0; j=0)
[1 6]9 (i=0; j=1)
[1 6 9] (i=0; j=2)
1[6]9 (i=1; j=1)
1[6 9] (i=1; j=2)
1 6[9] (i=2; j=2)
Taking Don's answer above (which works perfectly), I came up with a slightly Groovy-er version of the same thing:
def number = 181
number = number.toString() as List
def results = (0..<number.size()).inject([]) { res, numDigits ->
res.addAll( (0..<number.size()-numDigits).collect { startPos ->
number[startPos..startPos + numDigits].join() as int
} )
res
}
println results
There is no need to go from Integer to String to List and then back to String with join(), as String already behaves quite like any sequence:
// Sorry for the silly name. Couldn't think of anything better :)
def subInts(num) {
def str = num as String
(1..str.length()).inject([]) { res, size ->
res += (0..str.length() - size).collect { i -> str[i..< i + size] as int }
}
}
assert subInts(169) == [1, 6, 9, 16, 69, 169]
Aside from having a little less conversions, this is a copy of tim_yates solution. Hope it helps.
STrictly algorithmically... You could do something like this:
num = 169
ar = []
while ( num >= 1 ) {
str = num.toString()
ar.add(str[str.indexOf('.')-1])
num = num/10.toInteger()
}
len = ar.size()
for ( i in 1..len-1 ) {
for (j in 0..len-i-1) {
str = ""
for ( k in 0..i) {
str += ar.get(j+k)
}
ar.add(str)
}
}
I think that should work.
oneliner
(0..<n.size()).inject([]) {a,b -> (0..<n.size()-b).each {a << (n[it] as Integer)};a}
精彩评论