1

I wrote the code as follows but it doesn't return the first recurring letter properly.

Example:

In the word "statistics" the recurring letters are s, t, and i. But the letter t recurs sooner than the letter s and i, but my program returns s instead of t.

What do I need to do for it to return t, using two for loops, as per the task in hand?

public class Main {
    public static char FRL(String word){
        for(int i = 0; i<word.length(); i++){
            for(int j = i+1; j<word.length(); j++){
                if(word.charAt(i) == word.charAt(j)){
                    return word.charAt(i);
                }
            }
        }
        return '0';
    }

    public static void main(String[] args) {
        String word = "statistics";
        if (FRL(word) != '0'){
            System.out.println(FRL(word));
        }else{
            System.out.println("No reccurring letter!");
        }
    }
}
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
PanicKk
  • 13
  • 7
  • Just to clarify, *two for loops* are an requirement? Just making sure cause that is an rather slow implementation and there are simple faster implementations. – Mushroomator May 22 '22 at 13:38
  • 1
    The 's' appears first in the test word, then the inner loop scans the remainder of the test word for another 's'. You need to redefine what "recurring sooner" means. – nicomp May 22 '22 at 13:39
  • @Mushroomator yes, It is a requirement of my "ADS" class, to implement 3 "algorithms", 1. using 2 for loops or naive method (O(n^2)) 2. using an early exit from the loop 3. using dictionaries or sets – PanicKk May 22 '22 at 13:40
  • @nicomp By recurring sooner I mean which one recurs first: **s**tati**s**tics - 4 steps s**t**a**t**istics - 1 steps – PanicKk May 22 '22 at 13:42
  • 1
    Then your algorithm is incorrect. You need to take a step back and redesign the algo. The code isn't wrong, it just doesn't do what you think it should be doing. Design, then code. – nicomp May 22 '22 at 14:02

1 Answers1

1

You can reduce eliminate the nested loop and improve the performance by storing every encountered character in a HashSet:

public static char FRL(String word){
    Set<Character> seen = new HashSet<>();
    for(int i = 0; i < word.length(); i++) {
        char next = word.charAt(i);
        if (!seen.add(next)) {
            return next;
        }
    }
    return '0';
}

But if you have a requirement to use a nested loop, then you should fix the initialization expression and condition of the inner for loop, i.e. we should be check characters starting from index 0 inclusive and up to index i exclusive:

public static char FRL(String word) {
    for(int i = 0; i < word.length(); i++) {
        char next = word.charAt(i);
        for(int j = 0; j < i; j++){
            if(next == word.charAt(j)) {
                return next;
            }
        }
    }
    return '0';
}

By the way, getFirstRecuringLetter() would be a better method name than FRL.

Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
  • I'd recommend adding `char c = word.charAt(i)` as the first line of the outer loop body, and then refer to that instead of calling `charAt(i)` repeatedly within the inner loop. Not a huge efficiency difference in this specific case (unless some "words" are very long) but a good habit to get into. – Bobulous May 22 '22 at 14:50
  • @Bobulous Agree, it's better to introduce a variable. Amended. – Alexander Ivanchenko May 22 '22 at 15:14