使用 ArrayList 的 get 方法的错误答案
Wrong Answer using `get` method of ArrayList
在解决this问题时,我直接在条件检查中使用ArrayList
的get
方法在问题的一些测试用例上得到错误答案。
未通过测试用例的代码:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Stack <Integer> s= new Stack<>();
ArrayList <Integer> m= new ArrayList<>();
for(int i=0;i<n;i++){
int x=sc.nextInt();
if(x==1){
int y=sc.nextInt();
if(m.isEmpty() || y>=m.get(m.size()-1))
m.add(y);
s.push(y);
}
else if(x==2){
// Here I am using `get` to check the last value of ArrayList with the top of stack
if(m.get(m.size()-1)==s.peek()) {
m.remove(m.size()-1);
}
s.pop();
}
else {
System.out.println(m.get(m.size()-1));
}
}
}
}
但是当将相同的语法分配给变量并将其用于条件检查时,它通过了。
通过所有测试用例的代码:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Stack <Integer> s= new Stack<>();
ArrayList <Integer> m= new ArrayList<>();
for(int i=0;i<n;i++){
int x=sc.nextInt();
if(x==1){
int y=sc.nextInt();
if(m.isEmpty() || y>=m.get(m.size()-1))
m.add(y);
s.push(y);
}
else if(x==2){
// When assigning the same to a variable it passed all test cases.
int a = m.get(m.size()-1);
if(a==s.peek()) {
m.remove(m.size()-1);
}
s.pop();
}
else {
System.out.println(m.get(m.size()-1));
}
}
}
}
由于我是 Java 的新手,我对 ArrayList
的 get
方法的使用感到困惑。请向我解释 get
方法的内部工作原理,为什么它会失败,或者我错过了什么?
我没有看任务本身(因为问题应该是独立的,我不会访问随机链接)但我相信问题出在你在这里使用的类型上。
第一种情况,m.get(m.size()-1)==s.peek()
右边和左边都是Integer
。因此,当您使用 ==
符号时,您实际上是在比较对象引用。这种比较仅在某些时候有效(我相信它适用于 -128 到 127 范围内的整数)。您可以使用 equals
来解决这个问题。
另一方面,我们有 int a = m.get(m.size()-1); if(a==s.peek())
。在这里,在第一部分中,您首先得到 Integer
,但随后它被分配给一个 int
变量——拆箱发生在此处。然后,当你有一个条件时,你比较一个 int
和一个 Integer
。在这样的比较中,Integer
被拆箱为 int
并且这里发生了对简单 int
的比较(参见 JLS-5.6.2 中的第一点)。因此,它在这种情况下工作正常。
s
和 m
存储 Integer
个对象,你应该 永远不要 使用 ==
.[=22= 比较对象]
将 m.get(m.size()-1)==s.peek()
替换为 m.get(m.size()-1).equals(s.peek())
,您的代码将起作用。
您的第二种方法起作用的原因是,通过将 m.get(m.size()-1)
分配给 int
变量,Integer
值被取消装箱,然后完成比较 a==s.peek()
在 int
值上(s.peek()
中的值也未装箱)。
我认为问题与 Integer 类型的自动 boxing/unboxing 有关。
在声明中
if(a==s.peek())
比较是将整数值 (a) 与未装箱的整数 (s.peek()) 进行比较。
在声明中
m.get(m.size()-1)==s.peek()
比较是在两个整数值之间进行比较,即在两个引用之间进行比较。由于两个引用不同,相等性检查失败。
要修复最新的声明,您可以使用:
m.get(m.size()-1).intValue()==s.peek().intValue()
或者使用Integer类型的equals方法
在解决this问题时,我直接在条件检查中使用ArrayList
的get
方法在问题的一些测试用例上得到错误答案。
未通过测试用例的代码:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Stack <Integer> s= new Stack<>();
ArrayList <Integer> m= new ArrayList<>();
for(int i=0;i<n;i++){
int x=sc.nextInt();
if(x==1){
int y=sc.nextInt();
if(m.isEmpty() || y>=m.get(m.size()-1))
m.add(y);
s.push(y);
}
else if(x==2){
// Here I am using `get` to check the last value of ArrayList with the top of stack
if(m.get(m.size()-1)==s.peek()) {
m.remove(m.size()-1);
}
s.pop();
}
else {
System.out.println(m.get(m.size()-1));
}
}
}
}
但是当将相同的语法分配给变量并将其用于条件检查时,它通过了。
通过所有测试用例的代码:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Stack <Integer> s= new Stack<>();
ArrayList <Integer> m= new ArrayList<>();
for(int i=0;i<n;i++){
int x=sc.nextInt();
if(x==1){
int y=sc.nextInt();
if(m.isEmpty() || y>=m.get(m.size()-1))
m.add(y);
s.push(y);
}
else if(x==2){
// When assigning the same to a variable it passed all test cases.
int a = m.get(m.size()-1);
if(a==s.peek()) {
m.remove(m.size()-1);
}
s.pop();
}
else {
System.out.println(m.get(m.size()-1));
}
}
}
}
由于我是 Java 的新手,我对 ArrayList
的 get
方法的使用感到困惑。请向我解释 get
方法的内部工作原理,为什么它会失败,或者我错过了什么?
我没有看任务本身(因为问题应该是独立的,我不会访问随机链接)但我相信问题出在你在这里使用的类型上。
第一种情况,m.get(m.size()-1)==s.peek()
右边和左边都是Integer
。因此,当您使用 ==
符号时,您实际上是在比较对象引用。这种比较仅在某些时候有效(我相信它适用于 -128 到 127 范围内的整数)。您可以使用 equals
来解决这个问题。
另一方面,我们有 int a = m.get(m.size()-1); if(a==s.peek())
。在这里,在第一部分中,您首先得到 Integer
,但随后它被分配给一个 int
变量——拆箱发生在此处。然后,当你有一个条件时,你比较一个 int
和一个 Integer
。在这样的比较中,Integer
被拆箱为 int
并且这里发生了对简单 int
的比较(参见 JLS-5.6.2 中的第一点)。因此,它在这种情况下工作正常。
s
和 m
存储 Integer
个对象,你应该 永远不要 使用 ==
.[=22= 比较对象]
将 m.get(m.size()-1)==s.peek()
替换为 m.get(m.size()-1).equals(s.peek())
,您的代码将起作用。
您的第二种方法起作用的原因是,通过将 m.get(m.size()-1)
分配给 int
变量,Integer
值被取消装箱,然后完成比较 a==s.peek()
在 int
值上(s.peek()
中的值也未装箱)。
我认为问题与 Integer 类型的自动 boxing/unboxing 有关。 在声明中
if(a==s.peek())
比较是将整数值 (a) 与未装箱的整数 (s.peek()) 进行比较。
在声明中
m.get(m.size()-1)==s.peek()
比较是在两个整数值之间进行比较,即在两个引用之间进行比较。由于两个引用不同,相等性检查失败。
要修复最新的声明,您可以使用:
m.get(m.size()-1).intValue()==s.peek().intValue()
或者使用Integer类型的equals方法