Ik programmeerde laatst een recursieve functie, en om het e.e.a. wat te versnellen wilde ik er een tabel voor al uitgerekende functiewaarden bij maken. Omdat ik deze wilde bewaren tussen berekeningen door heb ik de functie in een klasse gezet.
Nu kreeg ik hele rare resultaten, en met asserts kwam ik erachter dat soms de functie nul (oftewel de standaardwaarde van een int) retourneerde.
Na behoorlijk wat debuggen heb ik de fout ontdekt, maar ik ben er nog niet achter waarom het fout gaat.
Hieronder de (versimpelde) code:
Heeft iemand enig idee van de precieze reden hiervan?
Is het dat de "table[a][b]" "te vroeg" wordt vertaald naar een "echte" geheugenlocatie of is het iets anders?
Nu kreeg ik hele rare resultaten, en met asserts kwam ik erachter dat soms de functie nul (oftewel de standaardwaarde van een int) retourneerde.
Na behoorlijk wat debuggen heb ik de fout ontdekt, maar ik ben er nog niet achter waarom het fout gaat.
Hieronder de (versimpelde) code:
Java:
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
| // F: N x N -> N \ {0} class F{ private int[][] table; public expandTable(a,b){ // Maak een nieuw 2-dimensionale tabel om de functiewaarden in op te slaan // Grootte [a+1][b+1] omdat 0 ook meeteld if(table==null){ table = new int[a+1][b+1]; } if(table.length < a+1 || table[0].length < b+1){ // Maak tabel aan met voldoende grootte int[][] newTable = new int[(a+1>table.length?a+1:table.length)][(b+1>table[0].length?b+1:table[0].length)]; // Kopieer tabel for(int i=0;i<table.length;i++){ for(int j=0;j<table[0].length;j++){ newTable[i][j] = table[i][j]; } } // Vervang referentie door refentie naar nieuw tabel table = newTable; } } // 1: Dit werkt niet public calc(int a, int b){ expandTable(a,b); if(table[a][b] != 0){ return table[a][b]; } if(iets){ table[a][b] = calc(a-1,b); }else if(iets){ table[a][b] = calc(a, b-1); }else{ table[a][b] = a+b+1; } return table[a][b]; } // 2: Dit werkt wel public calc(int a, int b){ expandTable(a,b); if(table[a][b] != 0){ return table[a][b]; } int result = 0; if(iets){ result = calc(a-1,b); }else if(iets){ result = calc(a, b-1); }else{ result = a+b+1; } table[a][b] = result; return table[a][b]; } // 3: Dit werkt ook, maar zorgt voor meer rekenwerk en geheugenruimte public calc(int a, int b, int[][] table){ expandTable(a, b, table); if(table[a][b] != 0){ return table[a][b]; } if(iets){ table[a][b] = calc(a-1,b, table); }else if(iets){ table[a][b] = calc(a, b-1, table); }else{ table[a][b]] = eengetal; } return table[a][b]; } } |
Heeft iemand enig idee van de precieze reden hiervan?
Is het dat de "table[a][b]" "te vroeg" wordt vertaald naar een "echte" geheugenlocatie of is het iets anders?
[ Voor 1% gewijzigd door dtech op 15-02-2009 11:34 . Reden: 1: opmaak gefixt 2: overtik foutje gefixt ]