我試圖把我的第一步放入Scala,並且練習我看了一下the google code jam storecredit excersize。我先用java試了一下,這足夠好了,現在我試圖將它移植到Scala。現在使用java集合框架,我可以嘗試進行直接的語法轉換,但最終我會在scala中編寫java,而這種做法會使目標失敗。在我的Java實現中,我有一個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));
}
}
是的,思考事情後來它是完全矯枉過正,我只需要排序數組。 – Martijn 2011-06-02 17:00:18
這實際上很漂亮(我不完全追隨,雖然我會盡管)。假設你的算法對於每個數字都是至關重要的(如果有一條記錄被散列到補碼中:賓果! DinoDNA; else {把它放在哈希表中按價格}}。你甚至不需要對它進行散列,但是使用一個數組的索引價格和值的列表索引,甚至可以節省散列函數的價格。 – Martijn 2011-06-02 20:45:06
@Martijn理論上這是正確的,但這可能是一個非常稀疏的數組。這就是爲什麼我建議位圖(Scala中的'IntMap') - 它們節省空間。問題在於Java將任何內存分配置零,所以如果爲10個項目創建一個長1000的數組,您將失去可能擁有的任何優勢。另一方面,整數的哈希是身份,這非常快。 – 2011-06-03 12:51:45