Since last night I have been working very hard trying to write a solution to the problem "0-1 Sequences" (https://open.kattis.com/problems/sequences) on Kattis. At this point, I am at my wits end. I keep getting the wrong answer on the third test case, and I've tried everything I can possibly think of to fix my code. I'm fairly certain that the formula I am using to compute the result is correct, and I haven't been able to find an example where it gives the wrong answer. I suspect the issue is something to do with how I am calculating the modulus, but I've written and rewritten the relevant parts of the code and I am still failing each time. Below is my code (sorry in advance, I've been working like a madman with not much regard for writing "nice" code).
import java.util.*;
import java.util.ArrayList;
public class oneZeroSequences {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
//leading zero's have no effect on the number of inversions,
//and we therefore get rid of them all right off the bat.
while(s.charAt(0)=='0'){
s=s.substring(1);
if(s.length()==0){
System.out.println(0);
System.exit(0);
}
}
System.out.println(findSum(s));
System.exit(0);
}
public static long findSum(String s) {
int m=1000000007;
long res = 0;
//if passed an empty string, the sum of inversions is obviously 0
if(s.length()==0){
return 0;
}
while(s.charAt(0)=='0'){
s=s.substring(1);
if(s.length()==0){
return 0;
}
}
//if the first character of the string is a question mark, we handle the case
//where that question mark is 1 first, and then remove the question mark since
//leading 0's have no effect on inversions.
while(s.charAt(0)=='?'){
res+=findSum("1"+s.substring(1))%m;
s=s.substring(1);
if(s.length()==0){
return res%m;
}
}
ArrayList<Integer> qArray = new ArrayList<Integer>();
int start=0;
int found;
//here we construct an array of the indices of question marks in the string
while(true){
found=s.indexOf('?', start);
if(found==-1){
break;
}
qArray.add(found);
start=found+1;
}
ArrayList<Integer> zeroArray = new ArrayList<Integer>();
start=0;
found=0;
//here we construct an array of the indices of 0's in the string
while(true){
found=s.indexOf('0', start);
if(found==-1){
break;
}
zeroArray.add(found);
start=found+1;
}
long k = qArray.size();
long a = zeroArray.size();
long zeroSum = sumArrayList(zeroArray);
long qSum = sumArrayList(qArray);
Double dres = 0.0;
//the formula for sum of inversions is as follows:
//2^k*(zeroSum) + 2^(k-1)*(qSum) - (a^2-a)*2^(k-1) - (2a-1)*2^(k-2) - (k^2+k)*2^(k-3)
//the following lines of code apply this formula, taking the modulus at each step.
if(k>=3){
res += (expBySquaringMod(2, k)*(zeroSum%m))%m;
//res=(res%m+m)%m;
res +=((expBySquaringMod(2, k-1))*(qSum%m))%m;
//res=(res%m+m)%m;
res -= ((((((a%m)*(a%m))%m)-a%m)%m)*expBySquaringMod(2,k-1))%m;
//res=(res%m+m)%m;
res -= (((((2*a-1)%m)*(k%m))%m)*expBySquaringMod(2,k-2))%m;
//res=(res%m+m)%m;
res-= (((((k%m)*(k%m))%m+k%m)%m)*expBySquaringMod(2, k-3))%m;
//res=(res%m+m)%m;
return res%m;
}
//the expBySquaringMod function will give incorrect
//results for negative exponents, hence the following code.
dres += ((Math.pow(2,k))*(zeroSum%m))%m;
dres=(dres%m+m)%m;
dres +=((Math.pow(2,k-1))*(qSum%m))%m;
dres=(dres%m+m)%m;
dres -= (((((a%m)*(a%m))%m-a%m)%m)*(Math.pow(2,k-1)))%m;
dres=(dres%m+m)%m;
dres -=((((2*a-1)%m*(k%m)%m)*(Math.pow(2,k-2))))%m;
dres=(dres%m+m)%m;
dres-=((((k%m)*(k%m)%m+k%m))%m*(Math.pow(2,k-3)))%m;
dres=(dres%m+m)%m;
res+=dres.intValue()%m;
return res%m;
}
public static int sumArrayList(ArrayList<Integer> list) {
int res = 0;
for(int d : list) {
res+=d;
}
return res;
}
//this function was written to deal with the massive powers of two required for the solution
public static long expBySquaringMod(int base, long exp) {
int m=1000000007;
long res=1;
if(exp%2==0) {
for(int i=0; i<exp/2;i++) {
res=(res*base*base)%m;
}
} else{
res=base;
for(int i=0; i<exp/2;i++) {
res=(res*base*base)%m;
}
}
return res;
}
}
Any help will be greatly appreciated. This problem has been causing me a lot of distress.
I am trying to find a way to generate inner loops on demand (and have the depth as a variable).
In the following example, I am trying to generate a list of references such as jobo.2.2.2.2.2.2 where each .2 is added in the inner loop.
Here is what I have at the moment when I implement the new loop manually for 5 level of depth (i, j, k, l):
public void buildTaskList(){
String jobName ="jobo";
String last="";
long max=3;
List<String> tasks = new ArrayList<>();
for (long i = 1; i <= max; i++) {
for (long j = 1; j <= max; j++) {
if (j==max){
last="*";
tasks.add(jobName+"."+i+"."+j+last);
}else {
last="";
for (long k = 1; k <= max; k++) {
if (k==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+last);
}else {
last="";
for (long l = 1; l <= max; l++) {
if (l==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+last);
}else{
last="";
for (long m = 1; m <= max; m++) {
if (m==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+"."+m+last);
}else{
last="";
for (long n = 1; n <= max; n++) {
if (n==max)last="*";else last="";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+"."+m+"."+n+last);
}
}
}
}
}
}
}
}
}
}
tasks.add(jobName+"."+(max+1)+last);
System.out.println(tasks);
}
The result here is:
jobo.1.1.1.1.1.1, jobo.1.1.1.1.1.2, jobo.1.1.1.1.1.3*, jobo.1.1.1.1.2.1, jobo.1.1.1.1.2.2, jobo.1.1.1.1.2.3*, jobo.1.1.1.1.3*, jobo.1.1.1.2.1.1, jobo.1.1.1.2.1.2, jobo.1.1.1.2.1.3*, jobo.1.1.1.2.2.1, jobo.1.1.1.2.2.2, jobo.1.1.1.2.2.3*, jobo.1.1.1.2.3*, jobo.1.1.1.3*, jobo.1.1.2.1.1.1, jobo.1.1.2.1.1.2, jobo.1.1.2.1.1.3*, jobo.1.1.2.1.2.1, jobo.1.1.2.1.2.2, jobo.1.1.2.1.2.3*, jobo.1.1.2.1.3*, jobo.1.1.2.2.1.1, jobo.1.1.2.2.1.2, jobo.1.1.2.2.1.3*, jobo.1.1.2.2.2.1, jobo.1.1.2.2.2.2, jobo.1.1.2.2.2.3*, jobo.1.1.2.2.3*, jobo.1.1.2.3*, jobo.1.1.3*, jobo.1.2.1.1.1.1, jobo.1.2.1.1.1.2, jobo.1.2.1.1.1.3*, jobo.1.2.1.1.2.1, jobo.1.2.1.1.2.2, jobo.1.2.1.1.2.3*, jobo.1.2.1.1.3*, jobo.1.2.1.2.1.1, jobo.1.2.1.2.1.2, jobo.1.2.1.2.1.3*, jobo.1.2.1.2.2.1, jobo.1.2.1.2.2.2, jobo.1.2.1.2.2.3*, jobo.1.2.1.2.3*, jobo.1.2.1.3*, jobo.1.2.2.1.1.1, jobo.1.2.2.1.1.2, jobo.1.2.2.1.1.3*, jobo.1.2.2.1.2.1, jobo.1.2.2.1.2.2, jobo.1.2.2.1.2.3*, jobo.1.2.2.1.3*, jobo.1.2.2.2.1.1, jobo.1.2.2.2.1.2, jobo.1.2.2.2.1.3*, jobo.1.2.2.2.2.1, jobo.1.2.2.2.2.2, jobo.1.2.2.2.2.3*, jobo.1.2.2.2.3*, jobo.1.2.2.3*, jobo.1.2.3*, jobo.1.3*, jobo.2.1.1.1.1.1, jobo.2.1.1.1.1.2, jobo.2.1.1.1.1.3*, jobo.2.1.1.1.2.1, jobo.2.1.1.1.2.2, jobo.2.1.1.1.2.3*, jobo.2.1.1.1.3*, jobo.2.1.1.2.1.1, jobo.2.1.1.2.1.2, jobo.2.1.1.2.1.3*, jobo.2.1.1.2.2.1, jobo.2.1.1.2.2.2, jobo.2.1.1.2.2.3*, jobo.2.1.1.2.3*, jobo.2.1.1.3*, jobo.2.1.2.1.1.1, jobo.2.1.2.1.1.2, jobo.2.1.2.1.1.3*, jobo.2.1.2.1.2.1, jobo.2.1.2.1.2.2, jobo.2.1.2.1.2.3*, jobo.2.1.2.1.3*, jobo.2.1.2.2.1.1, jobo.2.1.2.2.1.2, jobo.2.1.2.2.1.3*, jobo.2.1.2.2.2.1, jobo.2.1.2.2.2.2, jobo.2.1.2.2.2.3*, jobo.2.1.2.2.3*, jobo.2.1.2.3*, jobo.2.1.3*, jobo.2.2.1.1.1.1, jobo.2.2.1.1.1.2, jobo.2.2.1.1.1.3*, jobo.2.2.1.1.2.1, jobo.2.2.1.1.2.2, jobo.2.2.1.1.2.3*, jobo.2.2.1.1.3*, jobo.2.2.1.2.1.1, jobo.2.2.1.2.1.2, jobo.2.2.1.2.1.3*, jobo.2.2.1.2.2.1, jobo.2.2.1.2.2.2, jobo.2.2.1.2.2.3*, jobo.2.2.1.2.3*, jobo.2.2.1.3*, jobo.2.2.2.1.1.1, jobo.2.2.2.1.1.2, jobo.2.2.2.1.1.3*, jobo.2.2.2.1.2.1, jobo.2.2.2.1.2.2, jobo.2.2.2.1.2.3*, jobo.2.2.2.1.3*, jobo.2.2.2.2.1.1, jobo.2.2.2.2.1.2, jobo.2.2.2.2.1.3*, jobo.2.2.2.2.2.1, jobo.2.2.2.2.2.2, jobo.2.2.2.2.2.3*, jobo.2.2.2.2.3*, jobo.2.2.2.3*, jobo.2.2.3*, jobo.2.3*, jobo.3.1.1.1.1.1, jobo.3.1.1.1.1.2, jobo.3.1.1.1.1.3*, jobo.3.1.1.1.2.1, jobo.3.1.1.1.2.2, jobo.3.1.1.1.2.3*, jobo.3.1.1.1.3*, jobo.3.1.1.2.1.1, jobo.3.1.1.2.1.2, jobo.3.1.1.2.1.3*, jobo.3.1.1.2.2.1, jobo.3.1.1.2.2.2, jobo.3.1.1.2.2.3*, jobo.3.1.1.2.3*, jobo.3.1.1.3*, jobo.3.1.2.1.1.1, jobo.3.1.2.1.1.2, jobo.3.1.2.1.1.3*, jobo.3.1.2.1.2.1, jobo.3.1.2.1.2.2, jobo.3.1.2.1.2.3*, jobo.3.1.2.1.3*, jobo.3.1.2.2.1.1, jobo.3.1.2.2.1.2, jobo.3.1.2.2.1.3*, jobo.3.1.2.2.2.1, jobo.3.1.2.2.2.2, jobo.3.1.2.2.2.3*, jobo.3.1.2.2.3*, jobo.3.1.2.3*, jobo.3.1.3*, jobo.3.2.1.1.1.1, jobo.3.2.1.1.1.2, jobo.3.2.1.1.1.3*, jobo.3.2.1.1.2.1, jobo.3.2.1.1.2.2, jobo.3.2.1.1.2.3*, jobo.3.2.1.1.3*, jobo.3.2.1.2.1.1, jobo.3.2.1.2.1.2, jobo.3.2.1.2.1.3*, jobo.3.2.1.2.2.1, jobo.3.2.1.2.2.2, jobo.3.2.1.2.2.3*, jobo.3.2.1.2.3*, jobo.3.2.1.3*, jobo.3.2.2.1.1.1, jobo.3.2.2.1.1.2, jobo.3.2.2.1.1.3*, jobo.3.2.2.1.2.1, jobo.3.2.2.1.2.2, jobo.3.2.2.1.2.3*, jobo.3.2.2.1.3*, jobo.3.2.2.2.1.1, jobo.3.2.2.2.1.2, jobo.3.2.2.2.1.3*, jobo.3.2.2.2.2.1, jobo.3.2.2.2.2.2, jobo.3.2.2.2.2.3*, jobo.3.2.2.2.3*, jobo.3.2.2.3*, jobo.3.2.3*, jobo.3.3*, jobo.4*
Anyone knows how this can be simplified and controlled by a variable int depth=123; for example?
Thanks
This option avoids recursion, and simply counts as you would when deciding the next element in the sequence:
private static class LevelGenerator implements Iterator<String> {
private int[] current; // min,min,min => min,min,min+1 => ... max,max,max
private int min, max; // at each position in current[] array
private String next; // to be returned when next() is called
public LevelGenerator(int levels, int min, int max) {
this.current = new int[levels];
for (int i=0; i<levels; i++) this.current[i] = min;
this.next = output();
this.min = min;
this.max = max;
}
/**
* Int array to string
*/
private String output() {
StringBuilder sb = new StringBuilder();
for (int i : current) sb.append("." + i);
return sb.toString();
}
/**
* Updates current and next
* counts as a human would: increments the last index that is not yet `max`,
* and then places all elements after it to `min`
*/
private String step() {
for (int i=current.length-1; i>=0; i--) {
if (current[i] < max) {
current[i] ++;
for (int j=i+1; j<current.length; j++) {
current[j] = min;
}
return output(); // next step is ready
}
}
return null; // no next step
}
#Override
public String next() {
if (next == null) throw new IllegalStateException("iteration is finished");
String output = next;
next = step();
return output;
}
#Override
public boolean hasNext() {
return next != null;
}
}
public static void main(String ... args) {
LevelGenerator l = new LevelGenerator(3, 1, 4);
while (l.hasNext()) {
System.out.println("job" + l.next());
}
}
The output for this example would be:
job.1.1.1
job.1.1.2
job.1.1.3
job.1.1.4
job.1.2.1
job.1.2.2
job.1.2.3
job.1.2.4
job.1.3.1
job.1.3.2
job.1.3.3
job.1.3.4
job.1.4.1
job.1.4.2
job.1.4.3
job.1.4.4
job.2.1.1
...
job.4.4.4
You can use Recursion (see wiki https://en.wikipedia.org/wiki/Recursion_(computer_science))
for example (draft, not checking)
#Test
public void buildTaskList1() {
String jobName ="job";
int depth=5;
int max=3;
List<String> tasks = new ArrayList<>();
for (long i = 1; i <= max; i++) {
buildTaskListRecursion(max, depth, tasks, jobName + "."+i);
}
tasks.add(jobName+"."+(max+1)+"*");
}
public void buildTaskListRecursion(int max,int depth, List<String> tasks, String jobName){
String last="";
for (long j = 1; j <= max; j++) {
if (j==max){
last="*";
tasks.add(jobName+"."+j+last);
}else {
depth--;
if(depth > 0) {
buildTaskListRecursion(max, depth, tasks, jobName+"."+j);
} else {
tasks.add(jobName+"."+j);
}
}
}
}
Yes
1. Support indexes
Create a stack of indexes of the size of depth.
2. Handle the levels properly
You need a currentDepth index to know where you were. This is 0 at first. Whenever an item is increased, push a new item to the stack with 0 as index. Whenever an item is going beyond max, pop it from the stack and increment the previous element. When the first element is popped, you completed all the work
3. You will need to logically know where you were.
Alternatively you could generate code
But that's much more complicated.
EDIT
In agreement with Bdzzaid's legitimate request, I will briefly talk about the Composite Design Pattern. First, let's see a diagram from the page he shared with us:
Source: https://dzone.com/articles/composite-design-pattern-in-java-1
That's a good read I can wholeheartedly recommend to future readers. The idea is that we use the composition of very similar components in a tree-like manner. The pattern is applied on a stack in our case, which can be thought about as a tree having a single branch in all cases. The reason this is beneficial to think about in this way is that we might want to add support for multiple loops, maybe even in an assymmetryc manner at some point. Now, the components are the levels/indexes in our case and they, together form a composition of the stack (or, in more general terms, the tree).
This pattern can be reused in many different situations, so it is advisable to get familiar with it if you not already have.
I have a project that is to create an array aRoad with a distinct length. I need to shift elements through this array and delete the object in the end, when it reaches the element just behind aRoad[N].
Let's suppose:
I have a number of objects ("cars") N and an array ("road") with the length L (=4).
i = 0: car1 is at road[0].
i = 1: car1 is at road[1].
i = 2: car1 is at road[2], car2 spawns at road[0].
i = 3: car1 is at road[3], car2 is at road[1].
i = 4: car1 vanishes from the road, car2 is at road[2], car3 spawns at road[0].
My Car-class:
package traffic;
public class Vehicle {
private int bornTime;
private char destination;
public Vehicle(int bornTime, char destination){
this.bornTime = bornTime;
this.destination = destination;
}
public int returnTime() {
return bornTime;
}
public char returnDest() {
return destination;
}
public String toString() {
System.out.print(destination);
return null;
}
}
My problem is: as soon as an object is leaving the array I get an error because the Index is out of Range. I tried to cover this with an IF-condition and thanks to the first answer I was able to create the code update.
How do I get a system, like that to run in Java? My updated approach:
public static void main(String[] args) {
int time = 1;
char[] aRoad = new char[6]; // lane length
Vehicle[] carList = {new Vehicle(1, 'X'), new Vehicle(4, 'Y')};
while(time < 15){
for(Vehicle car : carList){
if (car != null ){
int pos = time - car.returnTime();
if (pos >= 0){
if (pos >= 1){
aRoad[pos-1] = 0;
}
if (pos == (aRoad.length)){
aRoad[pos-1] = 0;
car = null;
}
if (car != null){
aRoad[pos] = car.returnDest();
}
}
}
}
//PRINT ARRAY EACH ITERATION, SET time = time + 1
}
The output looks like:
[...]
time = 6: [ , , Y, , , X]
time = 7: [ , , , Y, , ]
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at traffic.Test1.main(Test1.java:19)
So my specific question is:
How do I prevent this exception without setting the X-object (-car) to null?
EDIT
Since the question was too unspecified I threw out all the useless information and tidied it up.
I will answer your most clear question, the answer to which should hopefully set you in the right direction.
but how do I actually create a lot of cars going down the road?
You may be getting stuck here because you haven't utilised your Vehicle object's borntime field. For each iteration of your while loop, a car's new position in the road should be be given by
current time - borntime
So if you have multiple cars and a while loop iterating over your time dimension
Vehicle car1 = new Vehicle(2, "X");
Vehicle car2 = new Vehicle(4, "Y");
...
int time = 2;
while(time < 10){
// calculate road positions
int car1Pos = time - car1.returnTime();
int car2Pos = time - car2.returnTime();
aRoad[car1Pos - 1] = 0;
aRoad[car1Pos] = car1.returnDest();
aRoad[car2Pos - 1] = 0;
aRoad[car2Pos] = car1.returnDest();
...
}
But whenever your code starts looking this repetitive its best to think in terms of more arrays and loops. Put the vehicles in a "Vehicle array" and loop over it to update each car's position in the array
Vehicle[] carList = {new Vehicle(2, "X"), new Vehicle(4, "Y")};
...
int time = 2;
while(time < 10){
for(Vehicle car : carList){
int pos = time - car.returnTime();
aRoad[pos-1] = 0;
aRoad[pos] = car.returnDest();
}
...
}
Once you have that working, the next step would be to dynamically add Vehicles to carList, perhaps every two seconds, and remove them from carList when they get to the end of the road. Using an ArrayList for your carList would be much easier for this part.
Note that I have not tested this code so their might be syntactic mistakes.
I'm trying to write a method that returns a sub lists and each containin the max value of strigns from a larger list.
I'm using iterator and backtrack recursion to achieve this, however - I'm not familiar with backtrack recursion. Any suggestions on how to make this work. Or if my code needs adjustments?
This is what I have so far:
private void printAnagrams(List<String> anagrams, int max, List<List<String>> listofLists) {
Iterator<String> iterate = anagrams.iterator();
String word = "";
while (iterate.hasNext()) {
for(int i = 0; i < anagrams.size(); i++) {
word = iterate.next();
listofLists.add(new ArrayList<>());
listofLists.get(i).add(word);
if (listofLists.size() == max) {
listofLists.add(new ArrayList<>());
// Continue new list
}
}
}
}
This is the method that calls the private method:
public void printAnagrams(String phrase, int max, List<List<String>> anagrams) {
if (anagrams == null || max < 0) {
throw new IllegalArgumentException();
} else if (max == 0) {
getWords(phrase);
} else
printAnagrams(phrase, max, anagrams);
}// End of printAnagram method
Sample output:
List:
[core, course, cs, cure, for, force, forces, four, of, off, offer, offers, or, our, ours, re, score, so, source, suffer, sure, us, use, user]
SubLists with max = 3:
[core, off, us]
[core, us, off]
[course, off]
[cure, off, so]
[cure, so, off]
[force, of, us]
[force, us, of]
I'm using an ArrayList to hold a history of objects. Each new object I add using the .add method, like:
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(currentWord != null)
{
wordHist.add(currentWord);
}
if(wordHist.size() > WORDHIST_MAX_COUNT)
{
wordHist.remove(0);
}
}
However I don't want this to grow indefinitely, but to be limited to a certain value. If it reaches this maximum value, I want the oldest object (index 0) to be removed, and the rest to be left shifted, so previous index 1 is now index 0, etc.
How can this be done?
Thanks
ArrayList is not really a good choice in this case, but it can by done by calling remove(0) method. But if you want to do that efficiently, a linked list is better
(edited to make it clear that LinkedList is not generally better than ArrayList, but only in this case)
If it reaches this maximum value, I want the oldest object (index 0) to be removed
Then do wordHist.remove(0). That will remove the element at index 0.
To be precise:
wordHist.add(new Word("hello"));
if (wordHist.size() > MAX_SIZE)
wordHist.remove(0);
As user658991 states however, you should be aware of that this is a linear operation, i.e., takes time proportional to the number of elements in the list.
You could do this in constant time using LinkedList methods add and removeFirst.
Another option would be to wrap an array, or ArrayList in a class called something like CircularArrayList. In circular list structures you'll override the oldest element when adding a new one.
Edit:
Your code works fine:
import java.util.*;
class Test {
static int WORDHIST_MAX_COUNT = 3;
static List<String> wordHist = new ArrayList<String>();
public static void add(String currentWord) {
// VERBATIM COPY OF YOUR CODE
if (true/*event.getAction() == MotionEvent.ACTION_UP*/)
{
if(currentWord != null)
{
wordHist.add(currentWord);
}
if(wordHist.size() > WORDHIST_MAX_COUNT)
{
wordHist.remove(0);
}
}
}
public static void main(String[] args) {
add("a");
add("b");
add("c");
for (int i = 0; i < wordHist.size(); i++)
System.out.printf("i: %d, word: %s%n", i, wordHist.get(i));
System.out.println();
add("d");
for (int i = 0; i < wordHist.size(); i++)
System.out.printf("i: %d, word: %s%n", i, wordHist.get(i));
}
}
Prints:
i: 0, word: a
i: 1, word: b
i: 2, word: c
i: 0, word: b <-- b is now at index 0.
i: 1, word: c
i: 2, word: d
Use the remove( ) method.
Using remove(0) will remove the element from the 0th index.
U can use list.remove(index)// here index being '0', this internally shifts rest of the array up. An alternative solution wud be to use a queue or dequeue.
One simple implementation of what Op De Cirkel suggested
import java.util.ArrayList;
import java.util.List;
public class SimpleCircularHistory {
private int sizeLimit, start = 0, end = 0;
boolean empty = false;
private List<String> history;
public SimpleCircularHistory(int sizeLimit) {
this.sizeLimit = sizeLimit;
history = new ArrayList<String>(sizeLimit);
}
public void add(String state){
empty = false;
end = (end + 1) % sizeLimit;
if(history.size() < sizeLimit){
history.add(state);
}else {
history.set(end, state);
start = (end + 1) % sizeLimit;
}
}
public String rollBack(){
if(empty){ // Empty
return null;
}else {
String state = history.get(end);
if(start == end){
empty = true;
}else {
end = (end + sizeLimit - 1) % sizeLimit;
}
return state;
}
}
public void print(){
if(empty){
System.out.println("Empty");
}else {
for(int i = start;; i = (i + 1) % sizeLimit){
System.out.println(history.get(i));
if(i == end) break;
}
System.out.println();
}
}
public static void main(String[] args) {
SimpleCircularHistory h = new SimpleCircularHistory(3);
h.add("a");
h.add("b");
h.add("c");
h.add("d");
h.add("e");
h.add("f");
h.print();
h.add("X");
h.add("Y");
h.rollBack();
h.rollBack();
h.print();
h.add("t");
h.add("v");
h.add("w");
h.print();
h.rollBack();
h.rollBack();
h.rollBack();
h.print();
h.rollBack();
h.print();
}
}
This would print out :
d
e
f
f
t
v
w
Empty
Empty
Yeah, I've noticed this behaviour in adroid's lists too. It's REALLY irritating.
Anyway, there is a way to get around it if I don't mind object creation/destruction and the resulting garbage collection (NEVER do this in a onDraw of a surfaceview or something).
What I do is basically have two tracking int's; one to place the new object, and one to remove it:
int trackInt = 0;
int removeInt = 0;
//and then, in the method/class you use this:
Object newobject = new Object();
//add to list
objectList.add(trackInt, newobject);
trackInt++;
if (bugList.size() > 20) //20 is the max number of object you want, ie the maximum size of the list
{
objectList.remove(removeInt);
trackInt = removeInt;
removeInt++;
if (removeInt > 19) //remember, the list is zero indexed!
{
removeInt = 0;
}
}
Commons-collections has exactly what you're looking for:
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/buffer/CircularFifoBuffer.html