我是scala的新手,并尝试转换查找scala中具有唯一(或不同)数字的数字的java代码。 例如
Input : 10 20
Output : 10 12 13 14 15 16 17 18 19 20 (Except 11)
java代码是
class Test
{
// Method to print unique digit numbers
// in range from l to r.
static void printUnique(int l, int r)
{
// Start traversing the numbers
for (int i=l ; i<=r ; i++)
{
int num = i;
boolean visited[] = new boolean[10];
// Find digits and maintain its hash
while (num != 0)
{
// if a digit occcurs more than 1 time
// then break
if (visited[num % 10])
break;
visited[num%10] = true;
num = num/10;
}
// num will be 0 only when above loop
// doesn't get break that means the
// number is unique so print it.
if (num == 0)
System.out.print(i + " ");
}
}
这里l和r是范围。
我等效的scala代码是
def printUnique(l:int,r:int)
| for(i <- l to r)
| {
| num=i
| val z = new Array[Boolean](10)
| while (num != 0)
| {
| if(z[num % 10])
<console>:8: error: identifier expected but integer literal found.
if(z[num % 10])
我不确定该错误。能否以最佳方式将代码转换为scala
答案 0 :(得分:3)
这是一个确定数字是否具有重复数字的谓词:
def distinctDigits(n: Int): Boolean = {
val s = n.toString
s.length == s.distinct.length
}
可以与filter
一起使用,以提供所需的列表
(10 to 20).filter(distinctDigits)
答案 1 :(得分:1)
我认为,代码中的错误是,在Scala中,访问Array
或任何其他集合的元素不是用方括号来完成的,而是用普通的方括号来完成的:
// wrong:
// array[index]
// correct:
array(index)
无论如何,它是Scala中的一种替代解决方案,它不依赖于String
方法,并且在本质上与原始代码类似,可能看起来像这样:
def getDigits(number: Int): Iterator[Int] =
Iterator.iterate(number)(_ / 10).takeWhile(_ != 0).map(_ % 10)
def hasUniqueDigits(number: Int): Boolean = {
val visited = Array.ofDim[Boolean](10)
getDigits(number).forall {
digit =>
if (visited(digit)) false
else {
visited(digit) = true
true
}
}
}
def getUniqueDigitNumbers(left: Int, right: Int): IndexedSeq[Int] =
left to right filter hasUniqueDigits
def printUnique(left: Int, right: Int): Unit =
getUniqueDigitNumbers(left, right) foreach println
答案 2 :(得分:0)
// this returns a stream of the number's digits,
// from right to left. It's lazily evaluated.
def digits(n: Int): Stream[Int] =
if (n == 0) Stream.Empty
else (n % 10) #:: digits(n / 10)
// Counts the number of a digit occurences instead of
// storing a flag in Array[Boolean]. In the latter case
// it would require `if`, while we don't need any here.
// It's lazy as well, so will not need excessive evaluations.
def copies(d: Stream[Int]) = {
val z = new Array[Int](10)
d.map { i => z(i) = z(i) + 1; z(i) }
}
// Here we check if any digit has more than 1 occurence. The
// evaluation will stop as soon as such a digit found.
def test(n: Int) = copies(digits(n)).exists(_ > 1)
10 to 20 filterNot (test) foreach (println)
答案 3 :(得分:0)
这应该解决
def getDistinctNumbers(start: Int, end: Int): List[Int] = {
if (start > end) return List.empty
val hasUniqueDigits: Int => Boolean = a => {
val str = a.toString
str.split("").distinct.size == str.length
}
// From the range filter only the elements which have unique digits
(start to end).toList.filter(hasUniqueDigits)
}
答案 4 :(得分:0)
def isUniqueDigits(n:Long):Boolean={
import scala.annotation.tailrec
@tailrec
val x = if(n<0) -n else n
val list:List[Int] = x match{
case x if(x>=0 && x<10) => List(x.toInt)
case x if(x>=10) =>toDig(x/10):+(x%10).toInt
}
list == list.distinct
}
在Scala REPL中:
scala> (738 to 778).filter(isUniqueDigits(_))
res14: scala.collection.immutable.IndexedSeq[Int] = Vector(738, 739, 740, 741, 742, 743, 745, 746, 748, 749, 750, 751, 752,
753, 754, 756, 758, 759, 760, 761, 762, 763, 764, 765, 768, 769)