diff options
Diffstat (limited to 'ws2015/eip/blaetter/05')
-rw-r--r-- | ws2015/eip/blaetter/05/Histogramm.java | 111 | ||||
-rw-r--r-- | ws2015/eip/blaetter/05/manifest | 1 |
2 files changed, 112 insertions, 0 deletions
diff --git a/ws2015/eip/blaetter/05/Histogramm.java b/ws2015/eip/blaetter/05/Histogramm.java new file mode 100644 index 0000000..87e6b4e --- /dev/null +++ b/ws2015/eip/blaetter/05/Histogramm.java | |||
@@ -0,0 +1,111 @@ | |||
1 | import java.awt.Rectangle; | ||
2 | import java.awt.Color; | ||
3 | import java.awt.Point; | ||
4 | |||
5 | class Histogramm { | ||
6 | |||
7 | public static final int SPACING = 1; | ||
8 | public static final int MIN_BAR_WIDTH = 2; | ||
9 | public static final int HEIGHT = 480; | ||
10 | public static final int LABEL_HEIGHT = 12; | ||
11 | public static final int MIN_WIDTH = 640; | ||
12 | |||
13 | public static final Color COLD = Color.blue; | ||
14 | public static final Color HOT = Color.red; | ||
15 | |||
16 | public static void main(String[] args) | ||
17 | { | ||
18 | if (args.length < 2) | ||
19 | { | ||
20 | System.err.println("Need at least two arguments"); | ||
21 | System.exit(2); | ||
22 | } | ||
23 | |||
24 | String input = ""; | ||
25 | for (int i = 1; i < args.length; i++) | ||
26 | input += args[i]; | ||
27 | |||
28 | char[] alphabet = args[0].toCharArray(); | ||
29 | // We convert to char[] instead of byte[] in order to be unicode aware | ||
30 | |||
31 | graph(alphabet, makeRelative(countOccurences(alphabet, input))); | ||
32 | // Why can’t we have nice things? Like function composition? | ||
33 | } | ||
34 | |||
35 | public static double[] makeRelative (int[] counts) | ||
36 | { | ||
37 | double[] relativeCounts = new double[counts.length]; | ||
38 | int max = 0; | ||
39 | |||
40 | // I'm sure there's a library function for this but I was too lazy to look | ||
41 | for (int c : counts) | ||
42 | if (c > max) | ||
43 | max = c; | ||
44 | |||
45 | for (int i = 0; i < counts.length; i++) | ||
46 | relativeCounts[i] = ((double) counts[i]) / max; | ||
47 | |||
48 | return relativeCounts; | ||
49 | } | ||
50 | |||
51 | public static void graph(char[] alphabet, double[] counts) | ||
52 | { | ||
53 | int minWidth = MIN_BAR_WIDTH * (counts.length) + SPACING * (counts.length - 1); | ||
54 | int width = Math.max(minWidth, MIN_WIDTH); | ||
55 | |||
56 | int barWidth = (width - SPACING * (counts.length - 1)) / counts.length; | ||
57 | |||
58 | GraphicsWindow gw = new GraphicsWindow(width, HEIGHT); | ||
59 | gw.setText("Histogramm"); | ||
60 | |||
61 | int x = 0; | ||
62 | |||
63 | for (int i = 0; i < counts.length; i++) | ||
64 | { | ||
65 | int height = (int) (counts[i] * HEIGHT); | ||
66 | Point corner = new Point(x, HEIGHT - height); | ||
67 | Rectangle bar = new Rectangle(corner.x, corner.y, barWidth, height); | ||
68 | boolean labelAbove = height <= LABEL_HEIGHT; | ||
69 | |||
70 | |||
71 | gw.setColor(color(counts[i])); | ||
72 | gw.fill(bar); | ||
73 | gw.setColor(labelAbove ? Color.black : Color.white); | ||
74 | gw.drawStringAt(String.format("%c", alphabet[i]), new Point(corner.x, corner.y + (labelAbove ? -5 : LABEL_HEIGHT))); | ||
75 | |||
76 | x += SPACING + barWidth; | ||
77 | } | ||
78 | |||
79 | gw.mouseClick(); | ||
80 | System.exit(0); | ||
81 | } | ||
82 | |||
83 | public static Color color(double c) | ||
84 | { | ||
85 | double r, g, b; | ||
86 | r = HOT.getRed() * c + COLD.getRed() * (1 - c); | ||
87 | g = HOT.getGreen() * c + COLD.getGreen() * (1 - c); | ||
88 | b = HOT.getBlue() * c + COLD.getBlue() * (1 - c); | ||
89 | return new Color((int) r, (int) g, (int) b); | ||
90 | } | ||
91 | |||
92 | public static int[] countOccurences(char[] alphabet, String input) | ||
93 | { | ||
94 | int[] count = new int[alphabet.length]; | ||
95 | |||
96 | for (int i = 0; i < alphabet.length; i++) | ||
97 | count[i] = 0; | ||
98 | |||
99 | for (char c : input.toCharArray()) | ||
100 | for (int i = 0; i < alphabet.length; i++) | ||
101 | if (alphabet[i] == c) | ||
102 | count[i]++; | ||
103 | |||
104 | /* We could skip right to the next input character as soon as we | ||
105 | * find a match but this implementation supports multiple occurences | ||
106 | * of a char in the alphabet (inefficiently) | ||
107 | */ | ||
108 | |||
109 | return count; | ||
110 | } | ||
111 | } | ||
diff --git a/ws2015/eip/blaetter/05/manifest b/ws2015/eip/blaetter/05/manifest index 0573ab5..b858ad4 100644 --- a/ws2015/eip/blaetter/05/manifest +++ b/ws2015/eip/blaetter/05/manifest | |||
@@ -1 +1,2 @@ | |||
1 | Histogramm.java | ||
1 | H5-2.pdf \ No newline at end of file | 2 | H5-2.pdf \ No newline at end of file |