2013-02-27 64 views
0

這是我的問題,爲此,我製作的節目Java程序佔用太多的內存

阿里巴巴做了四十大盜一招,並能夠捕獲它們 一個大山洞這是內家野狼。盜賊是沒有任何武器的 ,只有盜賊的首領有刀。沒有 武器,他們將無法與狼戰鬥,所以他們決定自殺而不是被活着吃掉。

他們都認爲他們會站成一個圈,他們每三個人就會自殺,但盜賊隊長不喜歡 這個想法,並沒有殺死自己的意圖。他計算他應該站在哪裏,以便他是最後一位。

HackerMan想根據這個故事建立一個遊戲,但不是 殺害,他決定參與者將離開遊戲,而不是每第三個位置,它將在每個第二個位置。當然 在這場比賽中參加者的人數將遠遠超過40人。

輸入

輸入的第一行是一個整數N(1 < = N < = 1000),該 指定的測試用例的數量。之後,每行包含一個 整數X(5 < = X < = 100000000)這是 遊戲中的參與者人數。

輸出

對於每組數據生成包含 參與者誰生存的位置的線。假設參與者具有序​​列 號從1到n,並且計數與人1,即開始, 第一人的離去是具有數2.

採樣輸入

樣本輸出

3 7月27日

這裏是我的解決方案

class SurvivalStrategy { 

    public int next; 
    public int value; 
    public boolean alive; 

    SurvivalStrategy(int n, int v) 
    { 
     this.next = n; 
     this.value = v; 
     this.alive = true; 
    } 

    public int getNext(){ 
     return this.next; 
    } 
    public void kill(){ 
     this.alive = false; 
    } 

    public void changeNext(int n){ 
     this.next = n; 
    } 


    public static void main(String[] args) throws IOException { 

     System.out.println("Enter the number of cases"); 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     String line = br.readLine(); 
     int N = Integer.parseInt(line); 
     int[] array = new int[N]; 
     for(int a = 0; a < N; a++) 
     { 
      System.out.println("Enter No. of theives in case " + (a + 1)); 
      array[a] = Integer.parseInt(br.readLine()); 
     } 
     for(int b = 0; b < N; b++) 
     { 
      try{ 

       int theives = 0; 
       theives = array[b]; 
       SurvivalStrategy[] people = new SurvivalStrategy[theives]; 
       int i = 0; 
       int nextctr = 2; 
       for(i = 0; i < people.length; i++) 
       { 
        people[i] = new SurvivalStrategy(nextctr, i + 1); 

        if(nextctr > people.length) 
        { 
         people[i] = new SurvivalStrategy(1, i + 1); 
        } 
        nextctr++; 
       } 

       int k = 0; 
       int nextguy = 0; 
       int survivers = people.length; 
       boolean CarryOnJatta = true; 
       int lastSurviver = 0; 
       while(CarryOnJatta) 
       { 
        if(k >= people.length) 
        { 
         k = 0; 
         k = k + 2; 
        } 
        if(people[k].alive) 
        { 
         //System.out.println(people[k].value + " is Alive"); 
         nextguy = people[k].getNext(); 
         if(people[nextguy - 1].alive) 
         { 
          people[nextguy - 1].kill(); 

          people[k].changeNext(people[nextguy - 1].next); 
          lastSurviver = people[k].value; 
          survivers--; 
         }else{ 
          k = k + 2; 
         } 
         k = k + 2; 
        }else{ 
         k = k + 2; 
        } 

        if (survivers == 1) 
        { 
         CarryOnJatta = false; 
         System.out.println("" + lastSurviver); 

        } 
       } 




      } catch(Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

我的程序給出的是小值的輸出,但不是大的值。 如果我嘗試與輸入(23987443)我得到java堆大小超過錯誤。 有什麼辦法可以改善這個程序的空間和時間複雜性。 我也打開其他算法,如果他們正在產生所需的輸出。

+0

我正在解決一個編碼挑戰,這是給出的問題,我寫了這個完整的代碼來解決問題,但我的程序正在佔用太多的內存和時間來返回所需的結果 – 2013-02-27 13:09:34

+1

問題聽起來類似於[this](http://en.wikipedia.org/wiki/Josephus_problem)。 – Dukeling 2013-02-27 13:16:40

+0

@Dukeling:沒錯,在那個頁面上有一個公式可以立即給出正確的答案。 – Groo 2013-02-27 14:17:33

回答

0

你可以嘗試分配更多的內存給JVM,還有最近的文章中有關此: Java Heap Space error from command line

+0

如果我只有256 MB內存來執行程序,該怎麼辦?我看到有幾個人已經完成了這些工作,他們的代碼正常工作,所以這就是爲什麼我很想知道我哪裏出了問題。因爲我的算法似乎工作得很好,它可能不是最有效的一個 – 2013-02-27 13:11:12

+0

@Ishan如果你只有256MB,則不能分配更多,在這種情況下,23987443 SurvivalStrategy對象似乎大約爲256MB。你必須通過消耗更少的內存來提高你的實現效率,沒有任何'技巧'來解決編碼挑戰門戶上的內存重構問題。 – us2012 2013-02-27 13:55:23

3

您分配至少23987443 *的sizeof在堆(SurvivalStrategy)內存 - 這將是圍繞每300MB單一的情況下,這是唯一的這行代碼之前:

SurvivalStrategy[] people = new SurvivalStrategy[theives]; 

我猜的挑戰是設計與有效的內存處理的優點,教你 - 所以不是一次分配整個內存,你需要處理你的物品一個接一個,這樣你就只能分配一些物品我讓這些不再需要的人被GC收集。

+0

2398744本身就是盜賊的數量,所以正在使用的內存是 23987443 * sizeof(SurvivalStrategy) – 2013-02-27 13:39:20

+0

我站得更正了,但只有在重新進入基於int b的循環之前,這纔是真實的。嘗試在探測器下運行4個23987443小偷 - 您會看到堆迅速增長到1.2GB(取決於您的機器和GC)。 – 2013-02-28 10:01:39

0

你可以使用循環LinkedList。將您的節點添加到列表中,並使用計數算法遍歷列表。每次有人丟失時,只需調用該人員的刪除,這將標記爲有資格進行垃圾回收(假設該列表僅包含對您的節點的唯一引用)。

更好的是,不需要在列表的第一個循環中一次添加所有人。如果他們是V迭代的倍數,你可以不加人。這應該會讓你的內存使用量增加很多。

這會節省堆上的空間,因爲你保持的最大尺寸是N,但會有更多的分配/釋放開銷。不過,linkedList.remove提供了O(1)的複雜性。我認爲它會清理你的代碼並且使它更容易理解