我为HackerRank BigSorting写了一个scala解决方案, 并在某些测试用例中获得RuntimeException。我测试了scastie中的输入,似乎问题是由一个非常长的字符串调用length()引起的,但同样的java solution没有问题,这是一个错误吗? 我的解决方案代码是:
object Solution {
def stringSort(x:String, y:String):Boolean = {
var result = true
if(x.length < y.length){
result = true
}else if(x.length > y.length){
result = false
}else{
var founded = false
var i = 0
while(i < x.length && !founded){
var xi = x.charAt(i)
var yi = y.charAt(i)
if(xi != yi){
result = xi < yi
founded = true
}
i += 1
}
}
result
}
def bigSort(unsorted:Array[String]):Array[String] = {
return unsorted.sortWith(stringSort)
}
def main(args: Array[String]) {
val sc = new java.util.Scanner (System.in);
var n = sc.nextInt();
var unsorted = new Array[String](n);
for(unsorted_i <- 0 to n-1) {
unsorted(unsorted_i) = sc.next();
}
print(bigSort(unsorted).mkString("\n"))
// your code goes here
}
}
例外是
java.lang.IllegalArgumentException: Maximum String literal length exceeded
at scala.tools.asm.ByteVector.putUTF8(ByteVector.java:213)
at scala.tools.asm.ClassWriter.newUTF8(ClassWriter.java:1114)
at scala.tools.asm.ClassWriter.newString(ClassWriter.java:1582)
at scala.tools.asm.ClassWriter.newConstItem(ClassWriter.java:1064)
at scala.tools.asm.MethodWriter.visitLdcInsn(MethodWriter.java:1187)
at scala.tools.asm.tree.LdcInsnNode.accept(LdcInsnNode.java:71)
at scala.tools.asm.tree.InsnList.accept(InsnList.java:162)
at scala.tools.asm.tree.MethodNode.accept(MethodNode.java:820)
at scala.tools.asm.tree.MethodNode.accept(MethodNode.java:730)
at scala.tools.asm.tree.ClassNode.accept(ClassNode.java:412)
...
java解决方案
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String[] unsorted = new String[n];
for(int i = 0; i < n; i++) unsorted[i] = in.next();
Arrays.sort(unsorted,new Comparator<String>() {
@Override
public int compare(String a, String b)
{
return StringAsIntegerCompare(a,b);
}
});
StringBuilder output = new StringBuilder("");
for(String num : unsorted)
output.append(num+"\n");
System.out.println(output);
}
static int StringAsIntegerCompare(String s1, String s2)
{
if(s1.length() > s2.length()) return 1;
if(s1.length() < s2.length()) return -1;
for(int i = 0; i < s1.length(); i++)
{
if((int)s1.charAt(i) > (int)s2.charAt(i)) return 1;
if((int)s1.charAt(i) < (int)s2.charAt(i)) return -1;
}
return 0;
}
}
答案 0 :(得分:2)
很奇怪java解决方案,询问每个字符串的长度,但Scala解决方案没有。
对于它的价值,可以在不调用任何length
元素的String
方法的情况下解决这一挑战。我使用isDefinedAt()
想出了一个公认的解决方案(21行代码),以确定String
元素的相对长度。
根据要求,这是我提出的解决方案。
对于那些不熟悉HackerRank挑战的人来说,main()
方法中非常差的Scala代码是提供的代码(即不是我的错!)。我写了sortum()
代码。
def sortum(arr:Array[String],start:Int = 0, end:Int = 1000000):Array[String] =
if (arr.length < 2) arr //only one of this length, return it
else if (end-start < 1) arr.sorted //multiple of the same length, sort them
else { //partition into two groups
val mid = (end-start)/2 + start
val (a,b) = arr.partition(_.isDefinedAt(mid))
if (a.isEmpty) sortum(b,start,mid)
else if (b.isEmpty) sortum(a,mid+1,end)
else sortum(b,start,mid) ++ sortum(a,mid+1,end)
}
def main(args: Array[String]) {
val sc = new java.util.Scanner (System.in);
var n = sc.nextInt();
var unsorted = new Array[String](n);
for(unsorted_i <- 0 to n-1) {
unsorted(unsorted_i) = sc.next();
}
sortum(unsorted).foreach(println)
}
它是用于根据长度分隔叮咬的基本二进制搜索模式。
当然,既然我们知道字符串.length
不是问题的根源,那么可以使用更简单的解决方案。
unsorted.map(_.length)
.zipWithIndex
.sortWith{case ((al,ax),(bl,bx)) =>
al < bl || (al == bl && unsorted(ax) < unsorted(bx))
}.foreach(x => println(unsorted(x._2)))
答案 1 :(得分:2)
我可以看到Java和Scala代码之间的唯一重要区别是Scala sortWith
创建了一个新数组,与Arrays.sort
不同(并且可能还有一些中间开销),因此您可以运行内存不足。你可以尝试
import scala.math.Ordering
import scala.util.Sorting
val byLength: Ordering[String] = ... // your implementation, similar to Java comparator
Sorting.quickSort(unordered)(byLength) // instead of sortWith, sorts in-place
有关相关文档,请参阅http://www.scala-lang.org/api/2.12.0/scala/math/Ordering.html和http://www.scala-lang.org/api/2.12.0/scala/util/Sorting $。html。