2016-01-05 99 views
1

我必須計算來自方陣的幾個子矩陣的和。我有這種格式的輸入:有更快的方法來計算子矩陣的總和嗎?

8 8 // matrix is 8 x 8 and there are going to be 8 submatrixes 
-5 -4 -6 -2 1 -8 6 -1 //first row of the matrix 
-9 7 -3 -7 2 0 -6 -2 // second row of the matrix etc. 
6 -8 2 6 -7 0 3 -5 
-1 3 9 4 -7 0 -5 -3 
-8 0 0 -6 -5 -7 -7 0 
2 7 6 2 -6 6 5 0 
-1 -7 8 -7 6 7 -2 1 
-8 -3 -5 2 -5 4 -1 -2 
0 2 3 6 //upperRow, leftColumn, lowerRow, rightColumn of submatrix 
2 6 4 6 
0 7 1 7 
7 4 7 4 
1 7 7 7 
2 7 6 7 
4 5 6 5 
6 2 7 5 

我需要計算所有子矩陣的總和(除其他外)。我的代碼工作正常(編譯,運行,給出正確的結果),但我的方法public static int total(int[][] M, int upperRow, int leftColumn, int lowerRow, int rightColumn)殺死所有的表現(我測量它)。確切地說,內部的循環殺死它。

有沒有更快的方式(更有效率)來計算子矩陣的總數?

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map.Entry; 

public class Main { 

    public static void display(int[][] a2d) { 
     for (int[] a : a2d) { 
      for (int val : a) { 
       System.out.print(val + " "); 
      } 
      System.out.println(); 
     } 
    } 

    public static int total(int[][] M, int upperRow, int leftColumn, int lowerRow, int rightColumn) { 
     int rows = lowerRow - upperRow + 1; 
     int cols = rightColumn - leftColumn + 1; 
     int sum = 0; 
     int columnToCopyFrom = leftColumn; 
     for (int i = 0; i < rows; i++) { 
      for (int j = 0; j < cols; j++) { 
       sum += M[upperRow][columnToCopyFrom]; 
       columnToCopyFrom++; 
      } 
      columnToCopyFrom = leftColumn; 
      upperRow++; 
     } 
     return sum; 
    } 



    public static void main(String[] args) throws Exception { 
     //BufferedReader br = new BufferedReader(new FileReader("input3")); 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     String[] firstLine = br.readLine().split(" "); 
     int n = Integer.parseInt(firstLine[0]); 
     int k = Integer.parseInt(firstLine[1]); 
     int[][] M = new int[n][n]; 
     for (int i = 0; i < n; i++) { 
      String[] rowContents = br.readLine().split(" "); 
      for (int j = 0; j < rowContents.length; j++) { 
       M[i][j] = Integer.parseInt(rowContents[j]); 
      } 
     } 

     int avgSum = 0; 
     int total; 
     HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); 
     for (int i = 0; i < k; i++) { 
      String[] rowContents = br.readLine().split(" "); 
      int upperRow = Integer.parseInt(rowContents[0]); 
      int leftColumn = Integer.parseInt(rowContents[1]); 
      int lowerRow = Integer.parseInt(rowContents[2]); 
      int rightColumn = Integer.parseInt(rowContents[3]); 
      total = total(M, upperRow, leftColumn, lowerRow, rightColumn); 
      //srednia 
      avgSum += total; 
      //klasy abstrakcji 
      if (!map.containsKey(total)) { 
       map.put(total, 1); 
      } else { 
       map.put(total, map.get(total) + 1); 
      } 
      //display(cutOut); 
     } 
     int maxCount = 0; 
     int maxAbstractionClass = Integer.MIN_VALUE; 
     ArrayList<Entry> list = new ArrayList<Entry>(); 
     for (Entry<Integer, Integer> entry : map.entrySet()) { 
      if (entry.getValue() > maxCount || (entry.getValue() == maxCount && entry.getKey() > maxAbstractionClass)) { 
       maxAbstractionClass = entry.getKey(); 
       maxCount = entry.getValue(); 
      } 

     } 
     for (Entry<Integer, Integer> entry : map.entrySet()) { 
     if(maxCount==entry.getValue()){ 
      list.add(entry); 
     } 
     } 
     System.out.print(map.size() + " " + list.size() + " " + avgSum/k); 

    } 
} 

我在HashMap

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map.Entry; 

public class Main { 
    public static HashMap<FourNumbers, Integer> mapOfTotals = new HashMap<FourNumbers, Integer>(); 
    public static void display(int[][] a2d) { 
     for (int[] a : a2d) { 
      for (int val : a) { 
       System.out.print(val + " "); 
      } 
      System.out.println(); 
     } 
    } 

    public static int total(int[][] M, int upperRow, int leftColumn, int lowerRow, int rightColumn) { 
     FourNumbers fourNumbers = new FourNumbers(upperRow, leftColumn, lowerRow, rightColumn); 
     if(mapOfTotals.containsKey(fourNumbers)){ 
      return mapOfTotals.get(fourNumbers); 
     } 
     int rows = lowerRow - upperRow + 1; 
     int cols = rightColumn - leftColumn + 1; 
     int sum = 0; 
     int columnToCopyFrom = leftColumn; 
     for (int i = 0; i < rows; i++) { 
      for (int j = 0; j < cols; j++) { 
       sum += M[upperRow][columnToCopyFrom]; 
       columnToCopyFrom++; 
      } 
      columnToCopyFrom = leftColumn; 
      upperRow++; 
     } 
     mapOfTotals.put(fourNumbers, sum); 
     return sum; 
    } 

    public static void main(String[] args) throws Exception { 
     //BufferedReader br = new BufferedReader(new FileReader("input3")); 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     String[] firstLine = br.readLine().split(" "); 
     int n = Integer.parseInt(firstLine[0]); 
     int k = Integer.parseInt(firstLine[1]); 
     int[][] M = new int[n][n]; 
     for (int i = 0; i < n; i++) { 
      String[] rowContents = br.readLine().split(" "); 
      for (int j = 0; j < rowContents.length; j++) { 
       M[i][j] = Integer.parseInt(rowContents[j]); 
      } 
     } 

     int avgSum = 0; 
     int total; 
     HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();//KLUCZEM jest nazwa klasy abstrakcji(suma), wartoscia jest liczba wystapien tej klasy abstrakcji 
     for (int i = 0; i < k; i++) { 
      String[] rowContents = br.readLine().split(" "); 
      int upperRow = Integer.parseInt(rowContents[0]); 
      int leftColumn = Integer.parseInt(rowContents[1]); 
      int lowerRow = Integer.parseInt(rowContents[2]); 
      int rightColumn = Integer.parseInt(rowContents[3]); 
      total = total(M, upperRow, leftColumn, lowerRow, rightColumn); 
      //srednia 
      avgSum += total; 
      //klasy abstrakcji 
      if (!map.containsKey(total)) { 
       map.put(total, 1); 
      } else { 
       map.put(total, map.get(total) + 1); 
      } 
      //display(cutOut); 
     } 
     int maxCount = 0; 
     int maxAbstractionClass = Integer.MIN_VALUE; 
     ArrayList<Entry> list = new ArrayList<Entry>(); 
     for (Entry<Integer, Integer> entry : map.entrySet()) { 
      if (entry.getValue() > maxCount || (entry.getValue() == maxCount && entry.getKey() > maxAbstractionClass)) { 
       maxAbstractionClass = entry.getKey(); 
       maxCount = entry.getValue(); 
      } 

     } 
     for (Entry<Integer, Integer> entry : map.entrySet()) { 
      if (maxCount == entry.getValue()) { 
       list.add(entry); 
      } 
     } 
     System.out.print(map.size() + " " + list.size() + " " + avgSum/k); 

    } 
} 

class FourNumbers { 
    int upperRow, leftColumn, lowerRow, rightColumn; 

    public FourNumbers(int upperRow, int leftColumn, int lowerRow, int rightColumn) { 
     this.upperRow = upperRow; 
     this.leftColumn = leftColumn; 
     this.lowerRow = lowerRow; 
     this.rightColumn = rightColumn; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + leftColumn; 
     result = prime * result + lowerRow; 
     result = prime * result + rightColumn; 
     result = prime * result + upperRow; 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     FourNumbers other = (FourNumbers) obj; 
     if (leftColumn != other.leftColumn) 
      return false; 
     if (lowerRow != other.lowerRow) 
      return false; 
     if (rightColumn != other.rightColumn) 
      return false; 
     if (upperRow != other.upperRow) 
      return false; 
     return true; 
    } 

} 
+1

的[計算在元素之和可能的複製有效的矩陣](http://stackoverflow.com/questions/2277749/calculate-the-sum-of-elements-in-a-matrix-efficiently) –

+0

@PhamTrung不,不,有,C++解決方案,我需要一個Java解決方案。 – majewa

+2

你需要一個java解決方案,所以你需要在你自己的工作。算法保持不變。當你理解我的鏈接中的概念時,實現很容易。 –

回答

0

剃光幾個milisecond通過記住總計如果計算所有子矩陣可以說你做這個

for (int i = 0; i < 4; i++) { 
     for (int j = 0; j < 4; j++) { 
      sum += M[i][j]; 
     } 
    } 
    stored[0][0]=sum; 

尺寸4x4的,然後對於所有後續的矩陣,您在結尾處添加一列或一行並減去ha的行或列■從正面

  sum = stored[0][0]; 

     for (int j = 0; j < 4; j++) { 
      sum -= M[0][j]; 
     } 
     for (int j = 0; j < 4; j++) { 
      sum -= M[j][0]; 
     } 

     for (int j = 0; j < 4; j++) { 
      sum += M[4][j]; 
     } 
     for (int j = 0; j < 4; j++) { 
      sum += M[j][4]; 
     } 

也離開了小矩陣,這是多餘的 - 你不需要添加額外的變量只是循環的變量足以

for (int i = 0; i < rows; i++) { 
     for (int j = 0; j < cols; j++) { 
      sum += M[upperRow][columnToCopyFrom]; 
      columnToCopyFrom++; 
     } 
     columnToCopyFrom = leftColumn; 
     upperRow++; 
    } 

    for (int i = upperRow; i <= loweRow; i++) { 
     for (int j = leftColumn; j <= rightColumn; j++) { 
      sum += M[i][j]; 
     } 
    }