Sorting scala中的搜索树
我正在尝试将我的第一步放在Scala中,为了练习,我看了一下。我首先在java中尝试了它,这已经足够好了,现在我正在尝试将它移植到Scala。现在有了java collections框架,我可以尝试直接进行语法转换,但最终我会用scala编写java,而这种方法无法达到目的。在我的Java实现中,我有一个Sorting scala中的搜索树,sorting,scala,collections,traversal,Sorting,Scala,Collections,Traversal,我正在尝试将我的第一步放在Scala中,为了练习,我看了一下。我首先在java中尝试了它,这已经足够好了,现在我正在尝试将它移植到Scala。现在有了java collections框架,我可以尝试直接进行语法转换,但最终我会用scala编写java,而这种方法无法达到目的。在我的Java实现中,我有一个PriorityQueue,我将其清空为一个Deque,并弹出末端,直到我们有宾果。这一切都使用可变集合,这给我的感觉是非常'非scala'。我认为更实用的方法是构造一个数据结构,它可以从最高到
PriorityQueue
,我将其清空为一个Deque
,并弹出末端,直到我们有宾果。这一切都使用可变集合,这给我的感觉是非常'非scala'。我认为更实用的方法是构造一个数据结构,它可以从最高到最低,从最低到最高进行遍历。我走对了吗?Scala库中是否提供了合适的数据结构,或者我应该在这里使用自己的数据结构
编辑:Java中更简单版本的完整代码。它应该在O(max(credit,inputchars))
中运行,并已成为:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class StoreCredit {
private static BufferedReader in;
public static void main(String[] args) {
in = new BufferedReader(new InputStreamReader(System.in));
try {
int numCases = Integer.parseInt(in.readLine());
for (int i = 0; i < numCases; i++) {
solveCase(i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void solveCase(int casenum) throws NumberFormatException,
IOException {
int credit = Integer.parseInt(in.readLine());
int numItems = Integer.parseInt(in.readLine());
int itemnumber = 0;
int[] item_numbers_by_price = new int[credit];
Arrays.fill(item_numbers_by_price, -1); // makes this O(max(credit,
// items)) instead of O(items)
int[] read_prices = readItems();
while (itemnumber < numItems) {
int next_price = read_prices[itemnumber];
if (next_price <= credit) {
if (item_numbers_by_price[credit - next_price] >= 0) {
// Bingo! DinoDNA!
printResult(new int[] {
item_numbers_by_price[credit - next_price],
itemnumber }, casenum);
break;
}
item_numbers_by_price[next_price] = itemnumber;
}
itemnumber++;
}
}
private static int[] readItems() throws IOException {
String line = in.readLine();
String[] items = line.split(" "); // uh-oh, now it's O(max(credit,
// inputchars))
int[] result = new int[items.length];
for (int i = 0; i < items.length; i++) {
result[i] = Integer.parseInt(items[i]);
}
return result;
}
private static void printResult(int[] result, int casenum) {
int one;
int two;
if (result[0] > result[1]) {
one = result[1];
two = result[0];
} else {
one = result[0];
two = result[1];
}
one++;
two++;
System.out.println(String.format("Case #%d: %d %d", casenum + 1, one,
two));
}
}
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.util.array;
公共类商店信用{
中的专用静态缓冲读取器;
公共静态void main(字符串[]args){
in=新的BufferedReader(新的InputStreamReader(System.in));
试一试{
int numCases=Integer.parseInt(in.readLine());
for(int i=0;i结果[1]){
一=结果[1];
二=结果[0];
}否则{
一=结果[0];
二=结果[1];
}
1++;
两个++;
System.out.println(String.format(“Case#%d:%d%d”),casenum+1,one,
二),;
}
}
我想知道,对于这样的问题,您使用复杂的数据结构(如PriorityQueue
和Deque
)试图实现什么。可以使用一对嵌套循环来解决此问题:
for {
i <- 2 to I
j <- 1 until i
if i != j && P(i-1) + P(j - 1) == C
} println("Case #%d: %d %d" format (n, j, i))
然而,如果这个数字等于它的补码,那就行不通了。换句话说,如果有两个p
使得p+p==C
。在这些例子中,这样的情况相当多。然后可以测试该条件,然后只使用indexOf
和lastinexof
——除了可能只有一个p
,这样p+p==C
,在这种情况下,这也不是答案
因此,我以更复杂的东西结束,在构建地图的同时测试补码的存在。以下是完整的解决方案:
import scala.io.Source
object StoreCredit3 extends App {
val source = if (args.size > 0) Source fromFile args(0) else Source.stdin
val input = source getLines ()
val N = input.next.toInt
1 to N foreach { n =>
val C = input.next.toInt
val I = input.next.toInt
val Ps = input.next split ' ' map (_.toInt)
val (_, Some((p1, p2))) = Ps.zipWithIndex.foldLeft((Map[Int, Int](), None: Option[(Int, Int)])) {
case ((map, None), (p, i)) =>
if (map isDefinedAt C - p) map -> Some(map(C - p) -> (i + 1))
else (map updated (p, i + 1), None)
case (answer, _) => answer
}
println("Case #%d: %d %d" format (n, p1, p2))
}
}
是的,后来考虑到这件事完全是过火了,我只需要对数组进行排序。这实际上相当漂亮(虽然我会处理它,但我没有完全遵循)。假设您的算法基本上适用于每个数字{如果有一条记录散列到补码:Bingo!DinoDNA;否则{将其放入一个由price散列的散列表中}}。您甚至不需要对其进行散列,而是使用一个数组,该数组的索引为price,值为list index,甚至可以为hashfunction保存price。@Martijn理论上是正确的,但这可能是一个非常稀疏的数组。这就是为什么我建议使用位图(
IntMap
在Scala中)——它们可以节省空间。问题是Java会将任何内存分配归零,因此,如果您创建一个1000长的数组来存储10个项目,那么您将失去可能拥有的任何优势。另一方面,整数的散列是恒等式,速度非常快。要真正进行微观优化,可能需要对散列函数使用左移位^n,动态负载因子约为.5,由积分和项数决定,由积分和项数决定n。显然取决于输入。YMMV
import scala.io.Source
object StoreCredit3 extends App {
val source = if (args.size > 0) Source fromFile args(0) else Source.stdin
val input = source getLines ()
val N = input.next.toInt
1 to N foreach { n =>
val C = input.next.toInt
val I = input.next.toInt
val Ps = input.next split ' ' map (_.toInt)
val (_, Some((p1, p2))) = Ps.zipWithIndex.foldLeft((Map[Int, Int](), None: Option[(Int, Int)])) {
case ((map, None), (p, i)) =>
if (map isDefinedAt C - p) map -> Some(map(C - p) -> (i + 1))
else (map updated (p, i + 1), None)
case (answer, _) => answer
}
println("Case #%d: %d %d" format (n, p1, p2))
}
}