Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 62bbfa2

Browse files
Merge pull request #63 from SzymonStankiewicz/subsequence-sum
Added interval sum array
2 parents 833341a + da73ae8 commit 62bbfa2

File tree

3 files changed

+252
-2
lines changed

3 files changed

+252
-2
lines changed

‎.travis.yml‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
before_script:
2+
- sudo apt-get install ant-optional
23
- export OPTS="-server -Xmx3072M"
34
- export JAVA_OPTS="${JAVA_OPTS} ${OPTS}"
45
- export ANT_OPTS="${ANT_OPTS} ${OPTS}"
@@ -9,12 +10,12 @@ language: java
910

1011
jdk:
1112
- oraclejdk8
12-
- oraclejdk7
13+
# - oraclejdk7
1314
# - oraclejdk6
1415

1516
# - openjdk8
1617
- openjdk7
17-
- openjdk6
18+
# - openjdk6
1819

1920
env:
2021
- TEST_SUITE=run_tests
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package com.jwetherell.algorithms.data_structures;
2+
3+
4+
/**
5+
* Implementation of array holding integer values which allows to count sum of elements in given
6+
* interval in O(log n) complexity.
7+
*
8+
* @author Szymon Stankiewicz <dakurels@gmail.com>
9+
*/
10+
public class IntervalSumArray {
11+
private List.ArrayList<Integer> values = new List.ArrayList<>();
12+
private List.ArrayList<Integer> prefSums = new List.ArrayList<>();
13+
14+
/**
15+
* Creates empty IntervalSumArray
16+
*/
17+
public IntervalSumArray() {
18+
values.add(0);
19+
prefSums.add(0);
20+
}
21+
22+
/**
23+
* Creates IntervalSumArray of given size filled with zeros.
24+
*
25+
* Complexity O(size).
26+
*
27+
* @param size size of IntervalSumArray
28+
*/
29+
public IntervalSumArray(int size) {
30+
this();
31+
for(int i = 0; i<size; i++) {
32+
values.add(0);
33+
prefSums.add(0);
34+
}
35+
}
36+
37+
/**
38+
* Creates IntervalSumArray filled with given values.
39+
*
40+
* Complexity O(n log n).
41+
*
42+
* @param values sequence of values for IntervalSumArray.
43+
*/
44+
public IntervalSumArray(Iterable<Integer> values) {
45+
this();
46+
for(Integer v: values)
47+
add(v);
48+
}
49+
50+
private static int greatestPowerOfTwoDividing(int x) {
51+
return x&(-x);
52+
}
53+
54+
private static int successor(int x) {
55+
return x + greatestPowerOfTwoDividing(x);
56+
}
57+
58+
private static int predecessor(int x) {
59+
return x - greatestPowerOfTwoDividing(x);
60+
}
61+
62+
/**
63+
* @return size of IntervalSumArray
64+
*/
65+
public int size() {
66+
return prefSums.size() - 1;
67+
}
68+
69+
/**
70+
* Adds value at the end of IntervalSumArray.
71+
*
72+
* Complexity O(log n).
73+
*
74+
* @param val value to be added at the end of array.
75+
*/
76+
public void add(int val) {
77+
values.add(val);
78+
for(int i = 1; i<greatestPowerOfTwoDividing(size()+1); i*=2)
79+
val += prefSums.get(size() + 1 - i);
80+
prefSums.add(val);
81+
}
82+
83+
/**
84+
* Set value at given index.
85+
*
86+
* Complexity O(log n)
87+
*
88+
* @param index index to be updated
89+
* @param val new value
90+
*/
91+
public void set(int index, int val) {
92+
if(index < 0 || index >= size()) throw new IndexOutOfBoundsException();
93+
index++;
94+
int diff = val - values.get(index);
95+
values.set(index, val);
96+
while(index <= size()) {
97+
int oldPrefSum = prefSums.get(index);
98+
prefSums.set(index, oldPrefSum + diff);
99+
index = successor(index);
100+
}
101+
}
102+
103+
/**
104+
* Return value with given index.
105+
*
106+
* Complexity O(1)
107+
*
108+
* @param index index of array.
109+
* @return value at given index.
110+
*/
111+
public int get(int index) {
112+
return values.get(index+1);
113+
}
114+
115+
/**
116+
* Return sum of values from 0 to end inclusively.
117+
*
118+
* Complexity O(log n)
119+
*
120+
* @param end end of interval
121+
* @return sum of values in interval
122+
*/
123+
public int sum(int end) {
124+
if(end < 0 || end >= size()) throw new IndexOutOfBoundsException();
125+
end++;
126+
int s = 0;
127+
while(end > 0) {
128+
s += prefSums.get(end);
129+
end = predecessor(end);
130+
}
131+
return s;
132+
}
133+
134+
/**
135+
* Return sum of all values inclusively.
136+
*
137+
* Complexity O(log n)
138+
*
139+
* @return sum of values in array
140+
*/
141+
public int sum() {
142+
return sum(size()-1);
143+
}
144+
145+
/**
146+
* Return sum of values from start to end inclusively.
147+
*
148+
* Complexity O(log n)
149+
*
150+
* @param start start of interval
151+
* @param end end of interval
152+
* @return sum of values in interval
153+
*/
154+
public int sum(int start, int end) {
155+
if(start > end) throw new IllegalArgumentException("Start must be less then end");
156+
int startPrefSum = start == 0 ? 0 : sum(start-1);
157+
int endPrefSum = sum(end);
158+
return endPrefSum - startPrefSum;
159+
}
160+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.jwetherell.algorithms.data_structures;
2+
3+
import org.junit.Test;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.Random;
8+
9+
import static org.junit.Assert.*;
10+
11+
public class IntervalSumArrayTest {
12+
13+
@Test
14+
public void properSumAllElementsTest() {
15+
IntervalSumArray sub = new IntervalSumArray();
16+
for(int i = 0; i<=100; i++)
17+
sub.add(i);
18+
for(int i = 0; i<=100; i++)
19+
assertEquals(i*(i+1)/2, sub.sum(i));
20+
assertEquals(100*101/2, sub.sum());
21+
}
22+
23+
@Test
24+
public void randomGeneratedTest() {
25+
Random generator = new Random(42);
26+
List<Integer> list = new ArrayList<>();
27+
for(int i = 0; i<=100; i++)
28+
list.add(i);
29+
IntervalSumArray sum = new IntervalSumArray(list);
30+
for(int i = 0; i<1000000; i++) {
31+
int pos = generator.nextInt(100);
32+
int val = generator.nextInt(2000000) - 1000000;
33+
sum.set(pos, val);
34+
list.set(pos, val);
35+
assertEquals(val, sum.get(pos));
36+
}
37+
38+
int s = 0;
39+
List<Integer> prefSum = new ArrayList<>();
40+
prefSum.add(s);
41+
for(Integer val: list) {
42+
s += val;
43+
prefSum.add(s);
44+
}
45+
46+
for(int i = 0; i<=100; i++) {
47+
for(int j = i; j<=100; j++) {
48+
assertEquals(prefSum.get(j+1) - prefSum.get(i), sum.sum(i, j));
49+
}
50+
}
51+
}
52+
53+
@Test
54+
public void setIndexOutOfRangeTest() {
55+
IntervalSumArray sum = new IntervalSumArray(100);
56+
boolean thrown = false;
57+
try {
58+
sum.set(101, 10);
59+
} catch (IndexOutOfBoundsException e) {
60+
thrown = true;
61+
}
62+
assertTrue(thrown);
63+
}
64+
65+
@Test
66+
public void sumIndexOutOfRangeTest() {
67+
IntervalSumArray sum = new IntervalSumArray(100);
68+
boolean thrown = false;
69+
try {
70+
sum.sum(101);
71+
} catch (IndexOutOfBoundsException e) {
72+
thrown = true;
73+
}
74+
assertTrue(thrown);
75+
}
76+
77+
@Test
78+
public void endBeforeStartTest() {
79+
IntervalSumArray sum = new IntervalSumArray(100);
80+
boolean thrown = false;
81+
try {
82+
sum.sum(101, 100);
83+
} catch (IllegalArgumentException e) {
84+
thrown = true;
85+
}
86+
assertTrue(thrown);
87+
}
88+
89+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /