Checking to see if array is full - java

If I have an Array Candy[] type;
and type = new Candy[capacity];
if the Array is full is capacity = type.length ?

Since you are using array, the size of array is determined during compilation. Thus if your intention is to check whether current array's index has reached the last array element, you may use the following condtion (possibly in a loop) to check whether your current array index is the last element. If it is true, then it has reached the last element of your array.
Example:
int[] candy = new int[10]; //Array size is 10
//first array: Index 0, last array index: 9.
for (int x=0; x < candy.length; x++)
if (x == candy.length - 1)
//Reached last element of array
You can check the size of the array by using:
candy.length
You check whether it is last element by using:
if (currentIndex == candy.length - 1) //Where candy is your array
Make sure you are using double equal == for comparison.
Single equal = is for assignment.

Java creates an array with capacity count of references to the Candy instances initializing array with the nulls. So any array in java is full and
type.length == capacity
is always true.
type = new Candy[capacity] is equivalent to
type = new Candy[] {null, null, null, /* capacity count of nulls */, null};

In the example you show type.length will always be equal to capacity(after the initialization). Also your array will always have capacity elements but they will initially all be null.

If you want to check if array is full (no null elements), use something like this:
//1
boolean b = false;
//2
for(int i = 0; i < type.length; i++){
if(type[i] == null){
b = true;
}
}
//3
if(b == false){
System.out.println("Array is full");
}
What does it mean?
//1. At beginning you have one boolean (b) which is false.
//2. If any value in your array is null, b will be true.
//3. You check if value of b is still false. If it is, that means that b is never changed, so array is full (no null elements) .

Related

Integer variable not following while loop conditions

I've been having an issue with my code concerning arrays and int variables. In the section that I have issues with, I'm trying to check if an array (in which the user inputs their own integers) is in an increasing order, and if it is in an increasing order, the array is printed; if not, an error message is displayed. I am trying to do this using int two variables, one called c1 and another called orderCheck1 (both initialized to 0).
int[ ] list1 = new int [10000];
int a1 =0;
int b1 =0;
int c1 =0;
int value1;
int orderCheck1 =0;
while (a1 ==0){
if (b1 < list1.length){
value1 = scan.nextInt();
//checks to see if value entered is positive
if (value1 >=0){
list1[b1] = value1;
b1++;
}
else{
a1 =1;
}
}
}
while (c1 <(list1.length-1)){
if (list1[c1] >list1[(c1+1)]){
orderCheck1 =1;
}
c1++;
}
if (orderCheck1 ==0){
for (int i =0; i < b1; i++){
System.out.print (list1[i] + " ");
}
}
else{
System.out.println ("ERROR: One or both arrays are not in an increasing order.);
}
Basically, if a number in the array is larger than the number following it, orderCheck will become 1. Later in the code, it checks if orderCheck1 is either zero or one. If orderCheck1 is zero, then the ints in the array are printed; if it is one, then the error message is displayed.
The issue is, no matter what I enter, orderCheck1 always becomes a one, so the error message is always printed. What is wrong with my code?
Note: When the user enters values into the array, they are supposed to enter a negative number to stop entering values.
The main problem, I believe, is that you've allocated a list of 10000 elements, and you don't use them all. Java initializes the elements to 0. (Note that in some other languages, a construct like this could initialize the elements to random garbage values.)
You then write a loop that inputs numbers until the user enters a negative number. This will set the first n elements of the loop for some number n. But the remaining elements do not get chopped off the array. They are still there, and they are still 0.
This causes a problem for this loop:
while (c1 <(list1.length-1)){
if (list1[c1] >list1[(c1+1)]){
orderCheck1 =1;
}
c1++;
}
Note that list1.length is still 10000, even though the user didn't enter 10000 values. Once an array is created with new int[10000] or something like that, that fixes the .length of the array. This length cannot be changed. That means c1 will go up to 9999, regardless of how many values were entered.
Therefore, at some point, you will hit a point where you start comparing to the 0 values that got put in the array when you created it. Since all the values the user entered are positive, that means list1[c1] > list1[c1+1] will be true when list[c1] is the last value entered, because list1[c1+1] will still be 0.
The solution is that instead of letting c1 go up to list1.length-1, you have to stop it when it gets to, I think, one less than the number of user entries. It looks like you already have a b1 that counts the number of entries, so the while needs to be changed to while (c1 <some-expression-that-uses-b1). I'll let you work on getting that upper limit right.
One more thing: When you have an array like this whose size isn't really known, it's better to use an ArrayList. Unlike an int[], an ArrayList<Integer> will grow as you add elements to it, and the size() method will return the actual number of elements added.
I would suggest a method:
static boolean isAscending(int[] nums) {
for (int i = 1; i < nums.length; i++)
if (nums[i - 1] > nums[i])
return false;
return true;
}
Note that this handles the edge case of arrays of size zero or one correctly.

How to check ALL elements of a boolean array are true

I have a boolean array whose size depends on the size of a randomly selected string.
So I have something like this:
boolean[] foundLetterArray = new boolean[selectedWord.length()];
As the program progresses, this particular boolean array gets filled with true values for each element in the array. I just want to print a statement as soon as all the elements of the array are true. So I have tried:
if(foundLetterArray[selectedWord.length()]==true){
System.out.println("You have reached the end");
}
This gives me an out of bounds exception error. I have also tried contains() method but that ends the loop even if 1 element in the array is true. Do I need a for loop that iterates through all the elements of the array? How can I set a test condition in that?
Using the enhanced for loop, you can easily iterate over an array, no need for indexes and size calculations:
private static boolean allTrue (boolean[] values) {
for (boolean value : values) {
if (!value)
return false;
}
return true;
}
There is a Java 8 one-liner for this:
boolean allTrue(boolean[] arr) {
return IntStream.range(0, arr.length).allMatch(i -> arr[i]);
}
boolean[] foundLetterArray = new boolean[5];
The memory allocation for the abow array is like
foundLetterArray[0],foundLetterArray[1],foundLetterArray[2],foundLetterArray[3],foundLetterArray[4]
Array index starts with 0 and the total memory count is 5 and the last array index is 4.
You are trying to get index 5 that is foundLetterArray[5] which does not exist. That's why you are getting the ArrayIndexOutofBoundsException
if(foundLetterArray[selectedWord.length()-1]==true){
System.out.println("You have reached the end");
}
Arrays in Java starts from index 0 and last index is always [array.length()-1]
As you are checking for foundLetterArray[selectedWord.length()] ,its giving you a array out of Bound Exception try foundLetterArray[selectedWord.length()-1]
Like:
if(foundLetterArray[selectedWord.length()-1]){
System.out.println("You have reached the end");
}
Indices in java, as well as most programming languages, are 0-based, meaning that individual elements in an array with n elements have indices 0, 1, 2, ..., n-1. The last element in an array is always at index array.length - 1.
Array index start from 0 so last index is always 1 less then array length so here you are trying to access last index + 1 by doing foundLetterArray[selectedWord.length()] this so it is throuing ArrayIndexBoundEception use array.lastIndex() method or subtract 1 form length.
Implementing this foundLetterArray[selectedWord.length()-1] You must take care about one thing if your array does not contains any elements then selectedWord.length() return 0 and again you will get same exception so Its good to check lengh before doing this foundLetterArray[selectedWord.length()-1].
do this
public boolean allTrue(boolean[] array) {
for (boolean b : array) {
if (!b) {
return false;
}
}
return true;
}
There is no 'one line' way of knowing whether all of the elements of an array meet a certain condition (there are libraries that take care of the looping for you, but you still need to write the condition). Querying array[x] will only tell you about the xth item in that array, so for your question you need to check every item.
Also, as other people have pointed out, array indices are 0-based, so the first element is at array[0] and the last at array[array.length() - 1].
My example uses an alternate looping construct known as for-each. This is appropriate when you don't need to modify the array contents, you only need to read from them. It avoids any messing around with indices.
You do the check only for last element in the array ( and do it wrong, above is described why ).
In order to get if arrays contains only true values you should check all of them.
boolean allAreTrue = true;
for (boolean val : foundLetterArray) {
allAreTrue = allAreTrue && val;
}
// at this line allAreTrue will contain true if all values are true and false if you have at least one "false"

Java ArrayList is throwing IndexOutOfBoundsException. Why?

This is my current progress on a project. I am trying to implement this ArrayList stuff but file continues to trow the same exception.
import java.util.*;
public class Numerican{
public static void main( String [] args ){
Scanner input = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<Integer>(10);
int count = input.nextInt() * 2;
while (count > 0){
array.add( 0 );
count = count - 1;
array.add(count, 2);
}
array.add(2, input.nextInt());
System.out.println(array.get(2));
}
}
It was my understanding that = new ArrayList<Integer>(10); would set the array size to 10. Did I do something wrong?
= new ArrayList<Integer>(10);
This line initializes the CAPACITY to 10, meaning the memory is allocated in the backend, but as far as you are concerned, the array is still empty.
Javadoc -
public ArrayList(int initialCapacity)
Constructs an empty list with the specified initial capacity.
This is why the calls to add might fail, if you try to add beyond the size of the ArrayList.
p.s. remember that add function takes index first and then element, when using the 2 parameter variant.
Edit:
ArrayList has 2 different member variables, size and capacity. Capacity is how much memory is allocated, size is how many elements are inserted by programmer.
Here, Capacity = 10, Size = 0;
According to the javadocs:
Constructs an empty list with the specified initial capacity.
Note that the ArrayList is empty (i.e. does not contain any items). The value indicates the capacity of the ArrayList which is the number of elements which can be added before more memory must be allocated.
On the other hand, calling add() actually adds an item to the ArrayList. In your example, array.add( 0 ); adds a 0 at the end of the list and array.add(count, 2); adds a 2 at index count. I suspect the problem is that count is not a valid index in your ArrayList. You should check what its value is by inserting an SOP or using a debugger.
count maybe >= 10, maybe souce code can answer you question:
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
rangeCheckForAdd():
/**
* A version of rangeCheck used by add and addAll.
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
if the index is out of range (index < 0 || index > size()) IndexOutOfBoundsException will be thrown.
So i think you are accessing index > size() of the list.
size() ===> Returns the number of elements in this list.
array.add(2, input.nextInt()); here is the possible exception when your list size is 1...
From my understanding of ArrayList, you need to add items to the list in a sequential index.
i.e. You cannot add an item to the 7th index position if 1 to 6 have not been filled in.
ArrayList.add(indexPosition, element);
If you add elements to the list, starting at indexPosition 0, and increasing the indexPosition by 1 each time, it should work.
Ex.
int i = 0;
(while i < 10){
array.add(i, numberToAdd);
i++; }
Hey seems like your Problem is because of the line
array.add(count, 2);
adds a 2 at index count
For example your input size is 5 then array.add(9,2); the array size is only 1 by that time as capacity and size are two different parameters for a ArrayList. So you can use a for loop instead of while to insert your values
for(int i=0; i<count;i++)
{
array.add(i,2);
}

How can I (more) easily compare two sets of numbers?

I have sets of three numbers, and I'd like to compare numbers in a set to another set. Namely, that each number in the first set is less than at least one number in the other set. The caveat is that the next numbers in the first set must be less than a different number in the second set (i.e., {6,1,6} would work against {8,8,2}, but {6,2,6} against {8,8,2} wouldn't). I have a working method, but it's brute force and ugly.
If we have setA and setB, and each of those have elements a, b, and c:
if(setB.a < setA.a)
if(setB.b < setA.b)
if(setB.c < setA.c)
return true;
else if(setB.b < setA.c)
if(setB.c < setA.b
return true;
and so on...
EDIT: I just realized you said these sets are hardcoded at 3 values. This is a super general algorithm for sets of any size.
For a 3-value set, you can do the same dumping and sorting of set elements, and then do:
if(setB.a < setA.a)
if(setB.b < setA.b)
if(setB.c < setA.c)
return true;
return false;
======================================================
A general algorithm:
This is the most efficient way I can immediately think of to do this.
pseudocode (more pythonic than java, sorry-- hopefully the comments explain):
list l1 = set1.items() //get the items out
list l2 = set2.items()
l1 = sort(l1)
l2 = sort(l2) //sort the lists
int set2idx1 = l1[0].find_closest_greater_than_value(l2) //binary search or something
if set2idx1 exists:
l2 = l2[set2idx1+1:] //in python this means l2 is reassigned to a subarray of l2 starting at set2idx1+1 going to the end of l2
else:
return false
for(int i=1; i<l1.len; i++)
int set2idxi = l1[i].find_closest_greater_than_value(l2) //binary search or something
if set2idxi exists:
l2 = l2[set2idxi+1:]
else
return false
return true
comment if anything doesn't make sense
EDIT EDIT:
explanation of the general algorithm for any interested parties:
dump the set elements into arrays
sort those arrays
iterate through the first array, seeing if there is a value in the 2nd array that is greater than the current value. If so, get the index of that value and lop off everything before and including that index and reassign the 2nd array variable to what remains.
if there ever is no such value (either because it doesn't exist or you've run out of values to test, return false). Otherwise, at the end, return true.
The idea here is that since the arrays are sorted, you know that any element that is greater than the matched element in the 2nd array will be greater than the element you're testing against in the 1st array. So you can just chop off the lower values, and since you don't want to use the same value, you can chop off the one you found, too. If you ever return false you know it's because either there were no greater values, either because the numbers in array1 were all greater than the numbers in array2, or because there weren't enough numbers in array2 greater than the numbers in array1.
What about the following pseudocode?
Condition(A : Set, B : Set) : Bool =
Let a := max(A), b := min(B) In
// Namely, that each number in the first set is less than at least one number in the other set
If a <= b Then
// the next numbers in the first set must be less than a different number in the second set
Condition(without(A, a), without(B, b))
Else
False
EndIf
Where without(A, a) means the set A minus the set {a}
It seems that a List would do better than a Set since your example includes duplicate elements. Simply:
1) Sort the two lists.
2) Trim off the first few elements from the second list until the sizes of the first and second list are equal.
3) Directly compare list1[i] with list2[i] for each i.
Code:
import java.util.*;
class Main {
public static void main (String[] args) {
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>();
list1.add(3); list1.add(7); list1.add(7);
list2.add(8); list2.add(8); list2.add(2); list2.add(1); list2.add(5);
//algorithm:
Collections.sort(list1);
Collections.sort(list2);
List<Integer> list3 = list2.subList(list2.size() - list1.size(), list2.size());
System.out.println(list1.size() + " " + list3.size());
boolean pass = true;
for(int i = 0; pass && i < list1.size(); i++)
if(list1.get(i) >= list3.get(i))
pass = false;
System.out.println(pass);
}
}

Figuring out if all but one array elements are identical

Does anyone know how I would work out if all elements in an array but one have the same value?
I have been trying to work it out for ages but cannot solve it. For example testing an array that has 5 elements to see if it has 4 identical values.
Thanks
Use a map.
Map<X, Integer> map = new HashMap<X, Integer>(); // where X is the array type
Integer ct;
for(X item : array){
ct = map.get(item);
if(ct == 0) ct = Integer.valueOf(1);
else ct = Integer.valueOf(ct.intValue()+1);
map.put(item, ct);
}
// now test if map.values() consists of Integer.valueOf(1) and (optionally)
// another positive integer (thx aioobe)
Step by Step:
Get the first element.
Loop all the array elements and count the number of times they don't
match that first element.
If all of the elements match, you have your answer (all are equal).
If only one of the elements do not match, you have your answer (one
is different).
If some of the elements do not match, you have your answer (more than
one is different).
In none of the elements match, get the second element and repeat the
test.
If only one of the elements do not match, again only one is different (the first one).
Else, the number of different elements is bigger than one.
The approach I would choose is:
iterate over all elements and put them in a Map (HashMap in Java).
the key is the element, and the value is the counter of the appearance.
example: your array: A A A A B
map:
A -> 4
B -> 1
After you have constructed that map it's easy to find out if your array matches that criteria.
The map must have exactly 2 elements (map.size()).
Exactly one of the elements has the counter 1.
If you assume that adding to a map happens in constant time you'll have an overall complexity of 2n (iterate over array and iterate over map).
I came up with this trick :-)
public static boolean allButOneSame(int[] arr) {
if (arr.length <= 1)
return arr.length == 1;
Arrays.sort(arr);
return arr[0] != arr[arr.length-1] &&
(arr[0] == arr[arr.length-2] ||
arr[1] == arr[arr.length-1]);
}
(Relies on comparable values such as integers though!)
Iterate array, by comparing 1st element and x+1 elements where x is 2,3,4,...array.length()
If comparison fails then increment a counter
if ((counter==0) || ((counter> 1) && (counter != array.length-1))) then condition is not met
counter=0 means, all are same elements
counter=array.length-1 means sorted order eg: 4,5,5,5,5,5,5
Complexity ->time: O(n), no extra space other than counter
Here's another approach:
public static <Item> boolean allButOneSame(List<Item> items) {
// Make sure we have 2 different elements (or 1 element in total)
if (new HashSet<Item>(items).size() != 2)
return items.size() == 1;
// Create a temporary copy
List<Item> tmp = new ArrayList<Item>(items);
// Remove all elements equal to the first one.
tmp.removeAll(Collections.singleton(items.get(0)));
// Check the number of remaining elements.
return tmp.size() == 1 || tmp.size() == items.size() - 1;
}
It takes a List as input. Use Arrays.asList if start with an array.
You could also add all array elements into a LinkedHashSet (no duplicates, insertion order is preserved) and look at the set's .size()

Categories