I have a class ArrayDeque where I take in a circular array and I'm trying to implement a function turntoString() to turn my Array into a string.
I'm currently stumped on how can I do this due to the fact that this is a circular array. Here is my code so far:
public class ArrayDeque<T> {
private int volume = 0;
private int size = 0;
private int head = 0;
private int tail = 0;
private Object[] A1;
public ArrayDeque(int volume) {
this.volume = volume;
A1 = new Object[volume];
}
public String turntoString() {
String S = "";
for (int x = 0; x < A1.length; x++) {
S += x;
}
return S;
However, this doesn't work for circular arrays. Can anyone please help explain how can I do this?
It's a very bad idea to name your class
ArrayDeque, given that java's built in library already has such a beast. If this is not homework, use that one. If it is, it's a bit odd to ask SO to 'do your homework' for you.The idea behind a circular array is that they do not start at
0, so yourfor (int x = 0loop is incorrect. They start atheadand they end attail, with the caveat that when you loop through it, the 'index' increment operation isn'ti++buti = (i + 1) % size, i.e. if your backing store (A1here) is 100 large, head is 98, and tail is 5, to loop through the whole thing in sequence, the indices you want to hit are:Key point here is the
%operator. It is crucial for circular implementations of any sort. If you don't recognize it, scroll to the end of this answer.This assumes
headis inclusive andtailis exclusive. If it isn't, change your code so that it works that way, the math is a ton easier, and doing ranges like[1, 2)so (start is inclusive, end is exclusive) is idiomatic java.That's your loop. Get rid of the
forloop.There are many more smaller problems with this code:
Superfluous data
The size of your ArrayDeque is
(length + tail - head) % length. There is no need to store it separately, and it significantly complicates matters by storing it separately. What if you fail to updatesizein accordance, for example? There's a ton more to test. Just don't do that. Similarly, the total length of the backing store is simplyA1.length, there is no need to separately store this, it just introduces opportunity for things to fall out of sync. Get rid of thevolumefield entirely.Failure to adhere to java standards
Variable names are
writtenLikeThis, so the right name isa1, notA1. Also, names should be descriptive; tha thing should be calleddataorstore, notA1.Shouldn't that method simply be called
toString()? If not, at least it should be calledturnToString, notturntoString.Your
Svariable inturntoStringshould be calleds.Bad string concatenation
x += ywhere x and y are strings is very expensive. You do it in the loop. It's gotO(n^2)performance behaviour because of this. Use a StringBuilder instead. So instead of:you do:
What's
%?It's the modulo operator. In basis
a % bmeans: Divide a by b, but toss the result in the garbage; what we care about is the remainder. 7 divided by 2 is 3 (toss that in the garbage, we don't care), with a remainder of 1 (ah, that's what we care about).However, that's generally not the right way to think about it. What
%does is make math circular. Stick% Xat the end of anything and it's basically saying: "... but do the operation on a number line that loops right back around at X". Hence why its so crucial for circular operations. It's an easy way to 'solve' the problem. For example, in a deque with volume 100, if I want to go: "What element is 50 to the right of the 80th element", in basis it's just 80+50, except that gives you 130 which is 'past' the range of your arraydeque. You want 30 instead.%100will do that: 130%100 is 30.One weird thing about
%is that it doesn't fix signs.-30%100is -30, not 30. This can be fixed by adding 100 to it all.(-30+100)%100is 70. This is what you want: Imagine I ask: We're at index 5. Now go 35 to the left.5-35is -30, but what we really want is store[70]. In general in 'circular math world' adding the total size of the loop is a no-op. If you have a circle of size 100 and ask 'go 100 elements to the right', that's just walking around the circle and does nothing. Hence you can always just add that to any index lookups.