Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my code print empty array([]) when I use text files?

When I define my array strings in this way:

String[] X = {"X","M","J","Y","A","U","Z"};
String[] Y = {"M","Z","J","A","W","X","U"};

my code works and it prints [M, J, A, U] which is the longest common subsequence of X and Y but when I define text files for the string arrays, which have the same input, then my code prints an empty array []. How can I solve this?

    public class LCS   {
    // Function to find LCS of String X[0..m-1] and Y[0..n-1]
    public static String A(String[] x, String[] y, int m, int n, int[][] T)
    {
        // return empty string if we have reached the end of
        // either sequence
        if (m == 0 || n == 0) {
            return new String();
        }
        // if last character of X and Y matches
        if (x[m - 1] == y[n - 1])
        {
            // append current character (X[m-1] or Y[n-1]) to LCS of
            // substring X[0..m-2] and Y[0..n-2]
            return A(x, y, m - 1, n - 1, T) + x[m - 1];
        }

        // else when the last character of X and Y are different

        // if top cell of current cell has more value than the left
        // cell, then drop current character of String X and find LCS
        // of substring X[0..m-2], Y[0..n-1]

        if (T[m - 1][n] > T[m][n - 1]) {
            return A(x, y, m - 1, n, T);
        }
        else {
            // if left cell of current cell has more value than the top
            // cell, then drop current character of String Y and find LCS
            // of substring X[0..m-1], Y[0..n-2]

            return A(x, y, m, n - 1, T);
        }
    }

    // Function to fill lookup table by finding the length of LCS
    // of substring X[0..m-1] and Y[0..n-1]
    public static void LCSLength(String[] x, String[] y, int m, int n, int[][] T)
    {
        // fill the lookup table in bottom-up manner
        for (int i = 1; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {

                // if current character of X and Y matches
                if (x[i - 1] == y[j - 1]) {
                    T[i][j] = T[i - 1][j - 1] + 1;
                }

                // else if current character of X and Y don't match
                else {
                    T[i][j] = Integer.max(T[i - 1][j], T[i][j - 1]);
                }
            }
        }
    }

    // main function
    public static void main(String[] args) throws IOException
    {
         String[] X =  read("C:\\Users\\fener\\Desktop\\producerconsumer\\Yeni Metin Belgesi.txt");
         String[] Y = read("C:\\Users\\fener\\Desktop\\producerconsumer\\Yeni Metin Belgesi (2).txt");

        //String[] X = {"X","M","J","Y","A","U","Z"}, Y = {"M","Z","J","A","W","X","U"};
        int m = X.length, n = Y.length;


        // T[i][j] stores the length of LCS of substring
        // X[0..i-1], Y[0..j-1]
        int[][] T = new int[m + 1][n + 1];

        // fill lookup table
        LCSLength(X, Y, m, n, T);

        String[] arr = A(X, Y, m, n, T).split("");
        // find longest common sequence
        System.out.print(Arrays.toString(arr));
        System.exit(0);
    }
    private static String[] read(String location) throws IOException {
        BufferedReader reader1 = new BufferedReader(new FileReader(location));
        String line;
        ArrayList<String> lines = new ArrayList<String>();
        while ((line = reader1.readLine()) != null) {
            lines.add(line);
        }
        reader1.close();
        String[] result = new String[lines.size()];
        for(int i=0; i<lines.size(); i++) {
            result[i] = lines.get(i);
        }
        return result;  
    }
    }
like image 979
John Montana Avatar asked Dec 15 '19 16:12

John Montana


People also ask

How to define empty array in NumPy?

As shown in syntax where array is array variable name and we define numpy empty array functions such as np.empty with shape of array and data types. The values returned by array are random and by default order of array is c it is used to define whether array is multidimensional or not.

How do I print an empty object in a loop?

Each time round the loop, you create a brand new empty object and overwrite the existing one. Then you try to print it's - empty - content, and surprised that its ... well ... empty. Remove the line that creates a new object and overwrites the array element from that loop, and see what happens. You're welcome!

How to print the data in an array?

To print the data in the array, you can use: Or, you can loop through the array with a for loop as others have posted in this thread. Show activity on this post. The current output is classtype@hashcode.

What does the weird text in the array text mean?

It's the default string representation of array (the weird text). Show activity on this post. To print the values use. Show activity on this post. That "weird number" is the reference for the array you printed out. It's the default behavior built into the java.lang.Object toString () method.


Video Answer


2 Answers

You should use Object#equals(Object anotherObject) method to compare strings or, in general, every object.
In your code, you are using == operator which will compare the strings references (if they are the same String instance) instead of their value.
Your code worked (when using Array initializer) because you initialized the String array with literals and two identical literals will be the same instance.
When you read a line in a file with readLine(), It creates a new String so two lines with the same content will result in two strings with the same value but different instances.
So, when comparing strings, use equals and your code will work.
See also: What is the difference between == and equals() in Java?

like image 198
dems98 Avatar answered Sep 22 '22 21:09

dems98


Here are some pointers:

In Java there is a difference in instantiating a String with the "" and by using the new String() constructor.

For example:

// Example 1
String a = "Y";
String b = "Y";
boolean result1 = a == b; // true

// Example 2
String c = new String("Y");
String d = new String("Y");
boolean result2 = c == d; // false

This happens because when you create a String using "Y", the actual object is allocated in a separate place in the heap called String Constant Pool. Any subsequent allocation of "Y" will return a reference to the same object in the String Constant Pool.

When you use new String("Y") you are saying that you want a completely new String object instance to be allocated in the common heap.

The == operator compares 2 objects to determine if they reference the same object instance, which in this case will be different as the Example 2 demonstrates.

For the presented code, the necessary changes are:

In A method

// return empty string if we have reached the end of
// either sequence
if (m == 0 || n == 0) {
    return "";
}
...

// if last character of X and Y matches
if (Objects.equals(x[m - 1], y[n - 1])) {
...

In LCSLength method

// if current character of X and Y matches
if (Objects.equals(x[i - 1], y[j - 1])) {
...

Here java.util.Objects.equals safely compares with == then equals().

By applying these changes the result is:

[M, J, A, U]

And lastly the read method do not need to be changed but could be simplified by using java.nio API:

private static String[] read(String folder, String filename) throws IOException {
    Path path = Paths.get(folder, filename);
    List<String> lines = Files.readAllLines(path);
    return lines.toArray(new String[0]);
}
like image 35
rbento Avatar answered Sep 25 '22 21:09

rbento