0

I have a method that accepts a String array as an argument. When I pass it e.g. {"4","4","4"}, it works perfectly fine. However it gives a different result when I pass it "444".split("").

FSA A = generateFSA2();

String s = "444";
String[] sArr = {"4","4","4"};
String[] sArr2 = s.split("");

System.out.println(s.split("").length + ", " + sArr.length + ", " + sArr2.length);

for(int i = 0; i < sArr.length; i++) {
    System.out.println("Strings equal = " + sArr[i].equals(sArr2[i]));
}

System.out.println("Accepted = " + isAccepted(A, s.split("")));
System.out.println("Accepted = " + isAccepted(A, sArr));
System.out.println("Accepted = " + isAccepted(A, sArr2));

Output:

3, 3, 3
Strings equal = true
Strings equal = true
Strings equal = true
Accepted = false
Accepted = true
Accepted = false

What's going on here?

EDIT: The isAccepted code:

public static Boolean isAccepted(FSA A, String[] w) {
    return isAcceptedRec(A, w, 0, 0);
}
private static Boolean isAcceptedRec(FSA A, String[] w, int q, int i) {
    if (i == w.length) {
        for (int qF : A.finalStates)
            if (q == qF)
                return true;
        return false;
    }
    for (Transition t : A.delta)
        if (t.from == q && t.label == w[i])
            if (isAcceptedRec(A, w, t.to, i + 1))
                return true;
    return false;
}

It's for testing FSAs. The code isn't mine, it is from an assessment, though obviously this isn't part of the assessment. I'm sticking to String arrays instead of splitting strings since apparently, that doesn't work.

CharlieDeBeadle
  • 129
  • 1
  • 1
  • 9
  • 3
    You would need to show the code of `isAccepted` (or ideally a [mcve]). I don't see any issues with the code you provided. – Marvin Mar 04 '21 at 15:03
  • @Marvin I've added the code. I can upload the FSA class if need be. – CharlieDeBeadle Mar 04 '21 at 15:09
  • 2
    It will be quite easy to find the reason if you know how to use a debugger. – Arvind Kumar Avinash Mar 04 '21 at 15:11
  • I can imagine that `{"4","4","4"}` is different from null-terminated String `"444"={"4","4","4","\0"} `, however `equals` doesn't care, maybe because in a sense they are equal... – gkhaos Mar 04 '21 at 15:12
  • 2
    @gkhaos null terminated string? in Java? how can the array have that extra string despite its size being 3 –  Mar 04 '21 at 15:23
  • 5
    With `t.label == w[i]` you are comparing string by identity. You should compare strings by content with `t.label.equals(w[i])` – Thomas Kläger Mar 04 '21 at 15:25
  • @ThomasKläger Thanks. isAccepted isn't my code, so I hadn't noticed that. Changing that fixes it. I'm surprised though, since I was filling the array with "4" rather than String variables. Would this be a compiler thing? – CharlieDeBeadle Mar 04 '21 at 15:37
  • `"4"` is not `==` `new String("4")` nor one substring of `"444"` (literals are interned see `String.intern()`, better see link provided by Thomas) –  Mar 04 '21 at 15:40
  • It doesn't matter how you use the constant "4" in your code - every time you write that constant you will get (at runtime) a reference to the same string object. `String.split()` however will always create new string instances for each of the substrings it generates. – Thomas Kläger Mar 04 '21 at 16:29
  • @CharlieDeBeadle Thomas Klager is right. What he didn't mention is that the overridden `equals` method in the `String` class INCLUDES the referential comparison of the objects. This is to not bother comparing the internal value of the object if they are not the same type or the exact same object (comparing it to itself). – hfontanez Mar 04 '21 at 19:22

0 Answers0