This code calculate the frequency of the array, please explain the dry run of the both for loop in the code

import java.util.Scanner;

public class freqArr {
public static void main(String args) {

    Scanner sc = new Scanner(System.in);

    System.out.println("Enter the length of the array: ");
    int size = sc.nextInt();

    int[] arr = new int[size];
    boolean[] visited = new boolean[size]; // To track counted elements

    // Take array input
    System.out.println("Enter the elements:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print("Enter element " + (i + 1) + ": ");
        arr[i] = sc.nextInt();
    }

    // Calculate frequency
    System.out.println("\nFrequencies of elements:");
    for (int i = 0; i < arr.length; i++) {

        if (visited[i]) continue; // Skip if already counted

        int count = 1;

        for (int j = i + 1; j < arr.length; j++) {
            if (arr[i] == arr[j]) {
                count++;
                visited[j] = true; // Mark duplicate as counted
            }
        }

        System.out.println(arr[i] + " : " + count);
    }

    sc.close(); // Always good practice to close Scanner
}

}

Hello.
It seems you put the backticks in the wrong place.
Can you fix it ?
Thanks.

As for the question I have little time right now but it looks you have 1 loop to input items in an array and another one to count.
the arr array is the source array and the visited shall count frequency.
The nested for is just starting from the next element not taken in account.
I’ll give a closer look later on.

Cheers.

As promised I explain the for loops.

I just rewritten them in C# but languages are pretty close.

First for loop is just gathering the data. I won’t explain further.
You certainly meant the 2 for loops that are nested later.

When you enter the loop, the visited array is containing as many bool (or boolean in Java) values as there are int values in the arr array. false being the default value in both C# and Java the behaviour is the same.

So there are an external loop that goes through the whole arr array. An an inner loop that goes through the visited array mostly.
The 1st item in visited should always be false. The reason for this is j starts at i+1 so visited[0] is never changed.
Also the counter will take the value 1 at every iteration of the external loop. You shall count the number you are determining the frequency.

What happens next is you will go through all other remaining numbers in the arr array.
Each of these will be compared with the value in arr[i].
Should an item share the same value, we increment counter along with marking the corresponding index as “visited” by setting the value to true.

Because the full array has been scanned, it is possible to display the frequency for such value right away by the end of the external loop.

In the next iteration i is 1 .

If arr[1] happen to be the same as arr[0] in the previous iteration (external loop) then visited[1] is true and thus we won’t process the loop for what happens to be the same value as before.

Otherwise the process happens again but further away in the table.

which means we scan the rest from arr[2] to the end of the array.

And so on.

I hope the explanation is clear enough.

Now this is for the general concept to use array because they are fairly easy to use.

You could use a multidimensioned array to avoid using 2 arrays but it is a bit more difficult to use.
Or any kind of collection that allows you to have duplicate values and multiple values in a single item. Or take advantage of OOP and actually store you POCO/POJO

for instance

class Item {
   int number;
   boolean visited;
}

List<Item> items = new List<Item>();

Here is the code I adapted to C#

// Topic CodeWithMosh
// https://forum.codewithmosh.com/t/this-code-calculate-the-frequency-of-the-array-please-explain-the-dry-run-of-the-both-for-loop-in-the-code/71198

const string emptyString = ""; // string.Empty is not allowed

Console.WriteLine("Enter the length of the array: ");
int size = ReadInt("The length should be a valid integer");

int[] arr = new int[size];
bool[] visited = new bool[size]; // To track counted elements

// Take array input
Console.WriteLine("Enter the elements:");
for (int i = 0; i < arr.Length; i++)
{
    Console.WriteLine("Enter element " + (i + 1) + ": ");
    arr[i] = ReadInt();
}


static int ReadInt(string customMessage = emptyString)
{
    const string defaultMessage = "The given value should be a valid integer";
    string strNumber = Console.ReadLine();
    int number;
    if (!Int32.TryParse(strNumber, out number))
    {
        throw new Exception(!customMessage.Equals(emptyString) ? customMessage : defaultMessage);
    }
    return number;
}

// Calculate frequency
Console.WriteLine("\nFrequencies of elements:");
for (int i = 0; i < arr.Length; i++)
{

    if (visited[i]) continue; // Skip if already counted

    int count = 1;

    for (int j = i + 1; j < arr.Length; j++)
    {
        if (arr[i] == arr[j])
        {
            count++;
            visited[j] = true; // Mark duplicate as counted
        }
    }

    Console.WriteLine(arr[i] + " : " + count);
}

Sum Up
A 1st loop gather values in an array
A 2nd loop goes through the array and take advantage of a companion visited array to manage counting logic : has the item already been counted ?
If it has been counted there is nothing to do and we go to the next iteration.
If it hasn’t been counted we scan the rest of the array to determine any duplicate value and apply said counting logic.

Cheers.

1 Like

thank you bro! your way of explanation is nice.