Kotlin Language Features Related to Null Handling

Any software engineer with a Java background would find the null handling features in the Kotlin language interesting. Let's summarize this topic with some examples. Nullable types: In Kotlin, types are non-nullable by default. If you want a variable to be able to hold a null value, you need to explicitly declare its type as nullable using the Type? syntax. For example, String? denotes a nullable string, while String represents a non-nullable string. Safe calls (?.): Kotlin introduces the safe call operator (?.) for handling nullable types. It allows you to safely invoke a method or access a property on a nullable object. If the object is null, the expression returns null instead of throwing a NullPointerException. Example: data class Person(val name: String, val age: Int, val address: String?) fun main() {     // Create a person with a nullable address     val person1 = Person("John Doe", 25, "123 Main Street")     val person2 = Person("Jane Doe", 30,...

Key-indexed counting for String manipulation in Java

We know that the fastest sorting algorithms that is based on comparing the elements (compareTo method) have a complexity of O(n logn)

But, is there a faster way for certain conditions? Yes.

Let's say we have an array of 11 letters with values from a to f

{e, e, f, a, b, a, a, c, d, a, a}

To sort these letters, we'll create an array that stores the frequencies of the letters. The index will be the letter itself. For example, for letter a, the index will be 0. For letter c, the index will be 2 and so on..

Frequency array for {a, b, c, d, e, f} is {5, 1, 1, 1, 2, 1}

The second step is calculating the cumulative counts which is {5, 6, 7, 8, 10, 11}

We need to use this cumulative counts to learn the position of each letter. We know that the position of letter a will be zero. So the array will start with 0 as the first position for a:

indexes:            {a, b, c, d, e, f , - }
cumulative array:   {0, 5, 6, 7, 8, 10, 11}

This cumulative array tells us this:
If your see letter a, put it in position 0.
If you see letter f, put it in position 10
...

Here is our resulting array for 11 letters: 
 0  1  2  3  4  5  6  7  8  9  10
{- ,- ,- ,- ,- ,- ,- ,-, -, -, - }

When we start scanning the original array of letters, the first letter we see is e, and it's position seems to be 8:

{- ,- ,- ,- ,- ,- ,- ,-, e, -, - }

After that, we have another e, so the position will be 8 +1 = 9

{- ,- ,- ,- ,- ,- ,- ,-, e, e, - }

Then we have an f, the position from cumulative array is 10:

{- ,- ,- ,- ,- ,- ,- ,-, e, e, f }

Then we have an a, the position is 0:

{a ,- ,- ,- ,- ,- ,- ,-, e, e, f }

If we go on doing this, the resulting array will be:

{a ,a ,a ,a ,a ,b ,c ,d, e, e, f }

Now let's write the code of this in Java:

public class Main {

    public static void main(String[] args) {

        char[] chars = {'e', 'e', 'f', 'a', 'b', 'a', 'a', 'c', 'd', 'a', 'a' };

        keyIndexSort(chars);

        System.out.println(new String(chars));
    }

    private static void keyIndexSort(char[] chars) {

        int[] frequencies = new int[chars.length + 1];

        for (int i = 0; i < chars.length; ++i) {
            ++frequencies[chars[i] - 'a' + 1];
        }

        for (int i = 0; i < chars.length; ++i) {
            frequencies[i + 1] += frequencies[i];
        }

        char[] sorted = new char[chars.length];

        for (char ch : chars) {

            sorted[frequencies[ch - 'a']++] = ch;
        }

        System.arraycopy(sorted, 0, chars, 0, sorted.length);
    }
}

The time complexity of this algorithm is O(n).

SUMMARY:

If we have keys in a certain range R (integer range), we can use these keys as array indexes. A first scan will give us the frequencies of values. Then we can create a cumulative count array with a second pass. The resulting cumulative array will give us the sorted positions of each value (from zero to R).

Usually there will be generic values attached to those keys, so for example, printing the keys using the cumulative array in 1 pass is not enough. We need to scan the original array of key-values and put them in the correct positions.

Comments

Popular posts from this blog

Trie Data Structure and Finding Patterns in a Collection of Words

Virtual Memory

NOTES ON COMPUTER ARCHITECTURE: Some important concepts in computer architecture