Why is this condition satisfied? (j == nElems) - java

I wrote this code to find an element in an array which is working pretty well but I do not understand how it works 100%. My question is, how come (j == nElems) when it only runs from 0 to 9? I've also noticed that the condition is satisfied outside the for loop when the search key is not found.
public class ArrayApp {
public static void main(String args[]) {
int nElems = 10;
int[] arr = new int[nElems];
int j;
int searchKey;
arr[0] = 77;
arr[1] = 99;
arr[2] = 44;
arr[3] = 55;
arr[4] = 22;
arr[5] = 88;
arr[6] = 11;
arr[7] = 00;
arr[8] = 66;
arr[9] = 33;
for (j = 0; j < nElems; j++) {
System.out.print(arr[j] + " ");
}
System.out.println();
//Find 66 in array
searchKey = 66;
for (j = 0; j < nElems; j++) {
if (arr[j] == searchKey) {
break;
}
}
if (j == nElems) {
System.out.println("Cant find " + searchKey);
} else {
System.out.println("Found " + searchKey + " in position " + j);
}
//Remove 55 from array
searchKey = 55; // delete item with key 55
for (j = 0; j < nElems; j++) { // look for it
if (arr[j] == searchKey) {
break;
}
}
for (int k = j; k < nElems - 1; k++) { // move higher ones down
arr[k] = arr[k + 1];
}
nElems--;
for (j = 0; j < nElems; j++) {
System.out.print(arr[j] + " ");
}
}
}

Let's have look at your for loop:
for (j = 0; j < nElems; j++) {
if (arr[j] == searchKey) {
break;
}
}
Here's what Oracle's documentation says about for loop:
The increment expression is invoked after each iteration through the
loop; it is perfectly acceptable for this expression to increment or
decrement a value.
So, in the above loop, j is incremented after each iteration. In the second last iteration, j will be nElems-1. It will execute the loop and increment j which would then make it equal to nElems.
As if condition is placed after the loop, by the time control reaches it, j will already be equal to nElems and hence, it will be true.

We can attempt to simplify what this for loop means
for (j = 0; j < nElems; j++) {
if (arr[j] == searchKey) {
break;
}
}
The for loop essentially breaks down to the following:
int j = 0;
int nElems = 10;
while(j < nElems) {
if(arr[j] == searchKey) {
break;
}
j++;
}
You can see that the final condition would be when j is equivalent to 10 (nElems).

for (j = 0; j < nElems; j++) {
if (arr[j] == searchKey) {
break;
}
}
nElems is 10. So j < nElems will be satisfied until j reaches 10. At that point, it will exit the loop. It'll only reach that point, however, if
arr[j] == searchKey
is never satisfied (ie. the search key is not found). So what you're seeing is that the search key is never found, j is incremented up until 10, at which point the loop is exited. At this point, j == nElems.

At the end of every iteration, j is incremented. After that, the stopping condition is tested. If that condition is true, the loop exits. Otherwise, it continues with the new value of j.
This means that your for loop runs as long as j < nElems. Once j == nElems, the for loop is done. Hence at the end, j must necessarily be equal to nElems; otherwise the loop will never terminate.

Related

How to add a condition so I don't go inside the loop

I am working on a code where you subtract respective elements of array 'a' from array'b' till you get all elements in array 'a' equal.
Condition is that a[i]>b[i] for subtraction.
But not every time getting all elements equal is possible, so in that case I would like my code to print '-1', how can I achieve it. I really tried hard to figure it out, don't give complex solutions as I am a beginner. you can subtract as many times you want.
Scanner sc = new Scanner(System.in);
short n = sc.nextShort();
short a[] = new short[n];
short b[] = new short[n];
for (short i = 0; i < n; i++) {// taking elements input
a[i] = sc.nextShort();
}
for (short i = 0; i < n; i++) {// taking elements input
b[i] = sc.nextShort();
}
short minimumOfArraya = 0;
for (short i = 0; i < n; i++) {// finding smallest element in array 'a'
for (short j = 0; j < n; j++) {
if (a[i] < a[j]) {
minimumOfArraya = a[i];
}
}
}
boolean allequal = false;
int counter = 0;
while (!allequal) {
for (short i = 0; i < n; i++) {// subtracting elements
if (a[i] == minimumOfArraya)
continue;
if (a[i] >= b[i]) {
a[i] -= b[i];
counter++;
}
}
for (short i = 0; i < n; i++) {
if (a[0] == a[i]) {
allequal = true;
} else {
allequal = false;
break;
}
}
}
for (int i = 0; i < n; i++) {// printing array 'a'
System.out.print(a[i] + " ");
}
System.out.println();
System.out.println(counter);
4
5 7 4 3//infinite loop
4 1 0 0
working input
5
5 7 10 5 15
2 2 1 3 5
output
5 5 5 5 5
8
The minimum can be found faster:
short minimumOfArraya = Short.MAX_VALUE;
for (short i = 0; i < n; i++) {// finding smallest element in array 'a'
if (a[i] < minimumOfArraya]) {
minimumOfArraya = a[i];
}
}
The for loop to check whether all are equal should initially have an allequal true,
and on finding a false, break. The initial setting to true was missing.
boolean allequal = false;
int counter = 0;
while (!allequal) {
for (short i = 0; i < n; i++) {// subtracting elements
if (a[i] == minimumOfArraya)
continue;
if (a[i] >= b[i]) {
a[i] -= b[i];
counter++;
}
}
allequal = true;
for (short i = 0; i < n; i++) {
allequal = a[0] == a[i];
if (!allequal) {
break;
}
}
}
If counter was not increased inside the while, the code may very well stay looping till overflow. If the minimum was 100 and 102 got 98 for instance.
If some of iterations producing number which is less than minimum, it clearly shows that you cannot make all elements equal. Check that after subtracting
while (!allequal) {
boolean impossible = false;
for (short i = 0; i < n; i++) {
if (a[i] < mimimumofArraya) {
impossible = true;
break;
}
if (a[i] == minimumOfArraya) continue;
if (a[i] >= b[i]) {
a[i] -= b[i];
counter++;
}
}
if (impossible) {
counter = -1;
break;
}
// The rest of your loop
...
}

Subtracting elements of an array from another array

I am fairly new to this so any help would be appreciated. I am trying to subtract elements of array 'b' from array 'a'( not removing but just subtracting) provided if the element of array 'a' is greater than the corresponding element of array 'b'.
I am not getting the required output its just printing the array I have entered
Scanner sc = new Scanner(System.in);
short n = sc.nextShort();
short a[] = new short[n];
short b[] = new short[n];
for (short i = 0; i < n; i++) {// taking elements input
a[i] = sc.nextShort();
}
for (short i = 0; i < n; i++) {// taking elements input
b[i] = sc.nextShort();
}
short m = 0;
for (short i = 0; i < n; i++) {// finding smallest element in array 'a'
for (short j = 0; j < n; j++) {
if (a[i] < a[j]) {
m = a[i];
}
}
}
boolean allequal = false;
while (!allequal) {
for (short i = 0; i < n; i++) {// subtracting elements
if (a[i] == m)
continue;
if (a[i] >= b[i]) {
a[i] -= b[i];
}
}
for (short i = 0; i < n; i++) {
for (short j = 0; j < n; j++) {
if (a[i] == a[j]) {
allequal = true;
} else {
allequal = false;
}
}
}
}
for (int i = 0; i < n; i++) {// printing array 'a'
System.out.print(a[i] + " ");
}
5
5 7 10 5 15
2 2 1 3 5
5 5 9 5 10
Your program does not enter while loop since you mistakenly used = operator in while (allequal = false) { which is assignment, not comparison. The correct form would be allequal == false which rewrites to !allequal. I didn't checked remaining code.
Note you should use good IDE which would prevent you doing such bug and provide debugger from which you could easily discover yourself.

How to count 1st duplicates value in array in Java

I have taken array int[] a = {33,33,5,5,9,8,9,9}; In this array so many values are duplicates means 33 comes twice & 5 also comes twice & 9 comes three times.
But I want to count the first value which is duplicate means 33 is first value which comes twice so answer would be 2.
I try:
public class FindFirstDuplicate
{
public static void main(String[] args) {
int c=0;
int[] a = {33,33,5,5,9,8,9,9};
outerloop:
for(int i = 0; i < a.length; i++)
{
for(int j = i+1; j< a.length; j++)
{
if(a[i] == a[j])
{
System.out.println(a[i]); //Duplicate value
c++;
break outerloop;
}
}
}
System.out.print("Count: "+c);
}
}
Output:
33
1
public class HelloWorld{
public static void main(String[] args) {
int[] a = {33,33,5,5,9,8,9,9};
for(int i = 0; i < a.length; i++)
{
int c=1; // we already found one.
// and we initialize this counter inside the loop,
// so that it is reset for each new starting number.
for(int j = i+1; j< a.length; j++) // we're starting from next number (reason we start with c=1)
{
if(a[i] == a[j])
c++;
}
if(c > 0) {
System.out.println("First uplicate value: "+ a[i] + " Count: " + c);
break; // we have to break out of the outer loop,
// so the inner loop can finish counting duplicates
}
}
}
}
Try something like:
int[] numbers = {33, 33, 5, 5, 9, 8, 9, 9};
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i< numbers.length; i++) {
if (!set.add(number[i])) {
System.out.println("first duplicate is " + number[i] + " and index is " + i);
break;
}
}
If the values in the array are non-negative and reasonably small, you can use a BitSet to store whether or not you have seen a value previously:
BitSet bits = new BitSet();
for (int i = 0; i < numbers.length; ++i) {
if (bits.get(numbers[i])) {
System.out.println("first duplicate at " + i + ": " + numbers[i]);
break;
}
bits.set(numbers[i]);
}
You could try this out:
int[] a = {33,33,5,5,9,8,9,9};
Integer[] uniques = new Integer[a.length];
Integer[] counts = new Integer[a.length];
int len = 0;
for(int num : a){
boolean matched = false;
for(int i = 0; i < len; i++){
if(num == uniques[i].intValue()){
matched = true;
counts[i] = new Integer(counts[i]+1);
break;
}
}
if(!matched){
uniques[len] = new Integer(num);
counts[i] = new Integer(1);
len++;
}
}
for(int i = 0; i < len; i++){
if(counts[i].intValue() > 1){
System.out.println("first duplicate is " + uniques[i] + " and number of times it appears " + counts[i]);
break;
}
}
In your code you exit both loops after the first duplicate is found, so any other occurences of the element would be ignored.
Also you start with c = 0. When you get to the second occurence, c will be incremented and be 1, not 2.
To count all elements simply change the loop condition of the outer loop and remove the break:
int c = 1;
int i;
for(i = 0; (c == 1) && (i < a.length); i++)
{
for(int j = i+1; j < a.length; j++)
{
if(a[i] == a[j])
{
c++;
}
}
}
System.out.println(a[i]); //Duplicate value
System.out.print("Count: "+c); // maybe do something else, if c == 1 (no duplicates)???
However SMA's answer describes a more performant way (for arbitrary input arrays) of finding the first duplicate. Once you found the second occurence of the first duplicate, you'd only need to count the number of occurences in the rest of the array to get the final count.

Move left if there is a zero

I am trying to create a program that will take an array of integers, say {2,0,32,0,0,8} that can be of any length, and make it so all of the nonzero numbers are to the left at the lower indexes, and all the zeros are moved to the end.
For example, {2,0,32,0,0,8} becomes {2,32,8,0,0,0}.
This array can be of any length and contain any nonnegative integers.
This is what I have so far:
public static int[] moveLeft(final int[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
for (int j = 0; j < a.length; j++) {
if (a[j] == 0) {
a[j] = a[i];
a[i] = 0;
}
}
}
}
return a;
}
However, when I do this, it doesn't work for the first and second characters. If I have {1,2,0,1} it will return {2,1,1,0} when it should return {1,2,1,0}. Any help?
Your inner loop should stop before index i. Change this
for (int j = 0; j < a.length; j++) {
to
for (int j = 0; j < i; j++) {
And then your code works for me.

Why does my Java "for" loop immediately end?

My first loop seems to build the array correctly and when I go to print out the results in the second "for" loop it immediately terminates. I cannot see the error. Here is the code:
public class CoinFlip
{
private static int Flip()
{
return (int)(2*Math.random()); //returns 0 or 1; 0=Tails,1=Heads
}
public static void main(String args[])
{
int HEADS = 1;
int[] ConsecArray = new int[1000]; // the odds of ever having more than 1000 HEADS consecutively flipped are nil
int Sequencecounter = 0;
for (int i = 0; i < ConsecArray.length; i++)
{
if (Flip() == HEADS)
{
Sequencecounter++;
}
else // we have a TAILS
{
// Check sequence counter, if > 0, logging to do...
if (Sequencecounter > 0)
{
// Update length counters
int index = Sequencecounter - 1;
ConsecArray[index]++;
Sequencecounter = 0;
}
// consecutive tails, continue in loop
}
}
int j = ConsecArray.length;
System.out.println("Length" + " " + "NumberRunsOfHeads");
for (int k = 0; k == j; k++)
{
int index = k + 1;
String bucketName = Integer.toString(index);
String bucketValue = Integer.toString(ConsecArray[k]);
System.out.println(bucketName + " " + bucketValue);
}
}
}
The first iteration of your 2nd loop:
k is 0
j is 1000
the test k == j fails
the loop never runs
Change
for (int k = 0; k == j; k++)
into
for (int k = 0; k < j; k++)
I think you mean either k <= j or k < j, but you put k == j. This is not true during first iteration, so loop body never executes.
for (int k = 0; k == j; k++)
{
int index = k + 1;
String bucketName = Integer.toString(index);
String bucketValue = Integer.toString(ConsecArray[k]);
System.out.println(bucketName + " " + bucketValue);
}
Instead of for (int k = 0; k == j; k++) (which is equivalent to if (k == j)) you meant to write or for (int k = 0; k < j; k++), i.e. loop j times, not loop as long as k == j.
This:
for (int k = 0; k == j; k++)
Should be this:
for (int k = 0; k < j; k++)
kett_chup is right. I Think you want "k < j". You're thinking of "until" rather than "for".

Categories