05 August 2008
设计基本的excel功能
Brute-Force
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class Excel {
class Value {
int val;
String[] numbers;
boolean isFormulae;
Value(int val) {
this.val = val;
isFormulae = false;
}
Value(String[] numbers) {
this.numbers = numbers;
isFormulae = true;
}
int getValue(Value[][] mat) {
if (!isFormulae) {
return val;
} else {
int sum = 0;
for (String s : numbers) {
String splittedNumbers[] = s.split(":");
if (splittedNumbers.length == 1) {
int row = getRow(splittedNumbers[0]), col = splittedNumbers[0].charAt(0) - 'A';
sum += mat[row][col].getValue(mat);
} else {
int r1 = getRow(splittedNumbers[0]), c1 = splittedNumbers[0].charAt(0) - 'A';
int r2 = getRow(splittedNumbers[1]), c2 = splittedNumbers[1].charAt(0) - 'A';
for (int i = r1; i <= r2; i++) {
for (int j = c1; j <= c2; j++) {
sum += mat[i][j].getValue(mat);
}
}
}
}
return sum;
}
}
private int getRow(String s) {
int row = 0;
for (int i = 1; i < s.length(); i++) {
row = row * 10 + (s.charAt(i) - '0');
}
return row;
}
}
Value[][] mat;
public Excel(int height, char width) {
mat = new Value[height + 1][width - 'A' + 1];
for (int i = 1; i <= height; i++) {
for (int j = 0; j < width - 'A'; j++) {
mat[i][j] = new Value(0);
}
}
}
public void set(int row, char column, int val) {
mat[row][column - 'A'] = new Value(val);
}
public int get(int row, char column) {
return mat[row][column - 'A'].getValue(mat);
}
public int sum(int row, char column, String[] numbers) {
mat[row][column - 'A'] = new Value(numbers);
return get(row, column);
}
}
/**
* Your Excel object will be instantiated and called as such:
* Excel obj = new Excel(height, width);
* obj.set(row,column,val);
* int param_2 = obj.get(row,column);
* int param_3 = obj.sum(row,column,numbers);
*/
观察者模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
class Excel {
private Cell[][] sheet;
public Excel(int height, char width) {
sheet = new Cell[height][width - 'A' + 1];
}
public void set(int row, char column, int val) {
getCell(row - 1, column - 'A').setValue(val);
}
public int get(int row, char column) {
return getCell(row - 1, column - 'A').getValue();
}
public int sum(int row, char column, String[] numbers) {
getCell(row - 1, column - 'A').setFormula(numbers);
return getCell(row - 1, column - 'A').getValue();
}
private Cell getCell(int row, int col) {
if (sheet[row][col] == null) {
sheet[row][col] = new Cell();
}
return sheet[row][col];
}
private int[] parse(String s) {
int[] result = new int[2];
result[0] = Integer.parseInt(s.substring(1, s.length())) - 1;
result[1] = s.charAt(0) - 'A';
return result;
}
private List<Cell> parseRange(String s) {
int[] left = parse(s.split(":")[0]);
int[] right = parse(s.split(":")[1]);
List<Cell> result = new ArrayList<>();
for (int i = left[0]; i <= right[0]; i++) {
for (int j = left[1]; j <= right[1]; j++) {
result.add(getCell(i, j));
}
}
return result;
}
class Cell {
int value = 0;
//Maintained by Observer
Map<Cell, Integer> observables = new HashMap<>();
//Maintained by Observables
Set<Cell> observers = new HashSet<>();
void setValue(int value) {
unRegister();
int oldValue = this.value;
this.value = value;
for (Cell cell : observers) {
cell.notify(this, value - oldValue);
}
}
int getValue() {
return value;
}
void setFormula(String[] numbers) {
unRegister();
List<Cell> observables = new ArrayList<>();
for (String s : numbers) {
if (!s.contains(":")) {
int[] cellPos = parse(s);
observables.add(getCell(cellPos[0], cellPos[1]));
} else {
observables.addAll(parseRange(s));
}
}
register(observables);
int oldValue = this.value;
computeValue();
for (Cell cell : observers) {
cell.notify(this, value - oldValue);
}
}
private void computeValue() {
value = 0;
for (Map.Entry<Cell, Integer> entry : observables.entrySet()) {
value += (entry.getKey().getValue() * entry.getValue());
}
}
//Called by Observable.
void notify(Cell cell, int valueChange) {
int oldValue = value;
value += (valueChange * observables.get(cell));
for (Cell cell1 : observers) {
cell1.notify(this, value - oldValue);
}
}
//Unregistered by Observer
void unRegister() {
for (Cell cell : observables.keySet()) {
cell.observers.remove(this);
}
observables.clear();
}
//Registered by Observer
void register(List<Cell> _observables) {
for (Cell cell : _observables) {
cell.observers.add(this);
observables.put(cell, observables.getOrDefault(cell, 0) + 1);
}
}
}
}