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;
}
}
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.
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!
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.
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.
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?
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]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With