0

My program checks multiple boolean arrays (length 30 each) and I would like to know if I already checked that array. I thought the best way to handle this problem would be to store all the arrays and search for the new array in the set of all the arrays but I don't know what structure I should use. At first, I though hashtable would be the best but it looks like I can't use them with arrays. I looked for set and list but I have no clue what to use !

Edit/clarification: Hey it's my first question here and I'm surprised how many answers I received, thanks a lot ! Lot of people says they are unsure about what exactly I'm looking for so I'll try to clarify:

I have multiple boolean arrays of length 30 where the order is important ( order of elements in the array).

I receive one array at a time and I want to check if I already received the same array (same element, same order). I don't need to store them( I don't need any index, I don't want to know how many arrays I received), don't need anything except to know if I already received the array.

z000by
  • 3
  • 2
  • set flag for checked array. ex. defined a boolean such as isChecked.... – logger Mar 31 '16 at 20:26
  • Can you transform your arrays into Lists?? using 'public static List asList(T... a)' from java.util.Arrays. That would be suitable for using with maps – Jorge Mar 31 '16 at 20:27
  • Actually looking for checked array, do you have any ressource I could use ? Just to be clear, I don't want to search a value in the array, I want to search if two arrays are equal (for multiple arrays). – z000by Mar 31 '16 at 20:28
  • Can you make it clear what you want? You want to check if there's already an equal array(elements are the same) or just mark array that you've already checked(same array)? – lkq Mar 31 '16 at 20:34
  • check if there is an equal array (all the same element, in the same order) – z000by Mar 31 '16 at 20:35

6 Answers6

1

A boolean array is basically a list of bits. Since array size is 30, and an int is a 32-bit value, you can convert the array into an int. With a long you could support arrays up to 64 in size.

So, first convert your array to an int:

private static int toBits(boolean[] array) {
    if (array.length > 32)
        throw new IllegalArgumentException("Array too large: " + array.length);
    int bits = 0;
    for (int i = 0; i < array.length; i++)
        if (array[i])
            bits |= 1 << i;
    return bits;
}

Then keep track using a Set<Integer>:

private Set<Integer> alreadySeen = new HashSet<>();

private boolean firstTime(boolean[] array) {
    return ! this.alreadySeen.add(toBits(array));
}

This provides a very fast and low-memory implementation that can handle lots of boolean arrays.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • This is definitely a smarter solution. +1 – lkq Mar 31 '16 at 20:52
  • Looks really good thanks ! Last question, if I had to convert the array to an int, I would loop through the array multiplying by 10*index the value at the index: (true, false true) = 1 + 10*0 + 100*1 = 101. Looks like you're using a different technique, or simply another notation ? What would be the best way to convert the bits. – z000by Mar 31 '16 at 20:59
  • @z000by Don't understand comment. I already gave the implemention to convert array to `int`, and it uses `1 << i`, not a multiply by 10. Bits are base-2 logic, not base-10. – Andreas Mar 31 '16 at 21:01
  • I'll juste google 1 << i and search a little bit (first time I see it, quite new to java), thx a lot already ! – z000by Mar 31 '16 at 21:02
  • @z000by See [Bitwise and Bit Shift Operators](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html) (The Java™ Tutorials), [How does bitshifting work in Java?](http://stackoverflow.com/questions/3312853/how-does-bitshifting-work-in-java) (StackOverflow), [Bitwise operation - Bit shifts](https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts) (Wikipedia). – Andreas Mar 31 '16 at 21:06
0

You can try an adjacency list or perhaps an array/arraylist of an Object that you call 'Pair' for example where this object has two attributes , the first is an array(the array you checked or didn't check yet) and the second attribute is a boolean value that denotes whether this array has been visited or not.

0

You can create a Wrapper class that holds array (content) and a flag. And, instead of storing array of arrays, you can store array of objects of this class. Have a look at the example below:

public class ArrayWrapper {

        private boolean checked;
        private boolean[] content;

        /**
         * @return the checked
         */
        public boolean isChecked() {
            return checked;
        }
        /**
         * @param checked the checked to set
         */
        public void setChecked(boolean checked) {
            this.checked = checked;
        }
        /**
         * @return the content
         */
        public boolean[] getContent() {
            return content;
        }
        /**
         * @param content the content to set
         */
        public void setContent(boolean[] content) {
            this.content = content;
        }
    }

Now, you can create a List<ArrayWrapper> or ArrayWrapper[], iterate through it and set checked to true once the array (content) is checked.

Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
0

Use Arrays.equals(array1, array2)

This method returns true if the two specified arrays of booleans are equal to one another. Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal.

I’m giving you a brute force solution.

List<boolean[]> arrs = new ArrayList<>();
while (true) {
    boolean[] receivedArr = receive();
    for (boolean[] existingArr : arrs) {
        if (Arrays.equals(existingArr, receivedArr)) {
            drop(receivedArr);
            break;
        }
        arrs.add(receivedArr);
    }
}
lkq
  • 2,326
  • 1
  • 12
  • 22
-1

You can use an array :)

If you have n arrays, then create a boolean array of size n. Let's call it checked[].

So if checked[5] == true, you already checked the fifth array.

Another option would be to use the index 0 of each array as the 'checked flag'.

Sebastian Breit
  • 6,137
  • 1
  • 35
  • 53
  • The input is a `boolean[30]` and question is whether that particular array has been seen before. – Andreas Mar 31 '16 at 20:56
-1

Thanks for your clarification!

HashMap is still a good answer using Arrays.hashCode() to create your key object. Like so:

HashMap<Integer, Boolean> checked = new HashMap<>();

/**
 * Returns true if already checked; false if it's new
 */
public boolean isChecked(Boolean [] array) {
    int hashCode = Arrays.hashCode(array);
    Boolean existing = checked(hashCode);
    if (existing == null) {
        checked.put(hashCode, true);
        return true;
    }
    return false;
}
Brian Risk
  • 1,244
  • 13
  • 23
  • @KeqiangLi his comment on his post which says "I want to search if two arrays are equal (for multiple arrays)" clarifies this. The Arrays.hashCode() approach will satisfy the equality requirement. – Brian Risk Mar 31 '16 at 20:41
  • He also says 'check if there is an equal array (all the same element, in the same order) ' – lkq Mar 31 '16 at 20:42
  • @z000by thanks for the clarification! check out my revised answer. – Brian Risk Mar 31 '16 at 20:48
  • `hashCode()` does not guarantee uniqueness, so two distinct boolean arrays may have the same hashcode. A map keyed by hashcode may therefore produce false positives. – Andreas Mar 31 '16 at 20:58