Java 为什么我的代码在使用文本文件时打印空数组([])?
以这种方式定义数组字符串时:Java 为什么我的代码在使用文本文件时打印空数组([])?,java,arrays,bufferedreader,Java,Arrays,Bufferedreader,以这种方式定义数组字符串时: String[]X={“X”、“M”、“J”、“Y”、“A”、“U”、“Z”}; 字符串[]Y={“M”、“Z”、“J”、“A”、“W”、“X”、“U”}; 我的代码工作并打印[M,J,A,U],这是X和Y中最长的公共子序列,但当我为具有相同输入的字符串数组定义文本文件时,我的代码打印一个空数组[]。我怎样才能解决这个问题 公共类LCS{ //用于查找字符串X[0..m-1]和Y[0..n-1]的LCS的函数 公共静态字符串A(字符串[]x,字符串[]y,int
String[]X={“X”、“M”、“J”、“Y”、“A”、“U”、“Z”};
字符串[]Y={“M”、“Z”、“J”、“A”、“W”、“X”、“U”};
我的代码工作并打印[M,J,A,U]
,这是X
和Y
中最长的公共子序列,但当我为具有相同输入的字符串数组定义文本文件时,我的代码打印一个空数组[]
。我怎样才能解决这个问题
公共类LCS{
//用于查找字符串X[0..m-1]和Y[0..n-1]的LCS的函数
公共静态字符串A(字符串[]x,字符串[]y,int m,int n,int[]T)
{
//如果已到达的结尾,则返回空字符串
//任一序列
如果(m==0 | | n==0){
返回新字符串();
}
//如果X和Y的最后一个字符匹配
如果(x[m-1]==y[n-1])
{
//将当前字符(X[m-1]或Y[n-1])附加到
//子串X[0..m-2]和Y[0..n-2]
返回A(x,y,m-1,n-1,T)+x[m-1];
}
//否则,当X和Y的最后一个字符不同时
//如果当前单元格的顶部单元格的值大于左侧单元格的值
//单元格,然后删除字符串X的当前字符并查找LCS
//子串X[0..m-2],Y[0..n-1]
if(T[m-1][n]>T[m][n-1]){
返回A(x,y,m-1,n,T);
}
否则{
//如果当前单元格的左侧单元格的值大于顶部单元格的值
//单元格,然后删除字符串Y的当前字符并查找LCS
//子串X[0..m-1],Y[0..n-2]
返回A(x,y,m,n-1,T);
}
}
//函数通过查找LCS的长度来填充查找表
//子串X[0..m-1]和Y[0..n-1]的
公共静态无效长度(字符串[]x,字符串[]y,整数m,整数n,整数[][]T)
{
//以自下而上的方式填写查找表
对于(int i=1;i您应该使用Object#equals(Object-anotherObject)
方法来比较字符串,或者通常比较每个对象。
在代码中,您使用的是=
运算符,该运算符将比较字符串引用(如果它们是相同的字符串
实例),而不是它们的值。
您的代码工作正常(使用数组初始值设定项时),因为您使用文本初始化了字符串数组,并且两个相同的文本将是同一个实例。
当您使用readLine()
读取文件中的一行时,它会创建一个新的字符串
,因此具有相同内容的两行将产生两个具有相同值但不同实例的字符串。
因此,在比较字符串时,使用equals
,您的代码将正常工作。
另请参见:以下是一些提示:
在Java中,使用“
和使用新字符串()
构造函数实例化字符串是有区别的
例如:
// 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
这是因为当您使用“Y”
创建字符串时,实际对象被分配到堆中称为字符串常量池的单独位置。任何“Y”
的后续分配都将返回对字符串常量池中相同对象的引用
当您使用newstring(“Y”)
时,您的意思是希望在公共堆中分配一个全新的String对象实例
=
操作符比较两个对象,以确定它们是否引用相同的对象实例,在本例中,这将与示例2所示的不同
对于所提供的代码,必要的更改包括:
在方法中
// 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])) {
...
// if current character of X and Y matches
if (Objects.equals(x[i - 1], y[j - 1])) {
...
在LCSLength方法中
// 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])) {
...
// if current character of X and Y matches
if (Objects.equals(x[i - 1], y[j - 1])) {
...
这里的java.util.Objects.equals
安全地与=
进行比较,然后是equals()
通过应用这些更改,结果是:
[M, J, A, U]
最后,read
方法不需要更改,但可以通过使用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]);
}
private static String[]read(字符串文件夹,字符串文件名)引发IOException{
Path Path=Path.get(文件夹,文件名);
列表行=文件。readAllLines(路径);
返回行.toArray(新字符串[0]);
}
注意java命名约定。方法名称应以小写字符开头。您还应学习如何使用调试器。它将帮助您找到错误文本文件的结构如何?@Demetrio每行有一个字母您的问题提供了大量代码,肯定不是一个简单的示例。请尝试缩短将问题中的代码降至最低。通常,在准备一个非常好的问题时,你会发现自己突然找到了答案。谢谢你。我做了你所说的一切,但这次我得到了第一个文本文件的最后一个元素,只需对代码进行3次更改。两次在一个方法中,一次在LCSLength方法中。请参阅我的更新写了日期的邮件。谢谢你提供的信息。它让我明白了