获取未被覆盖的equals方法使用hashCode
问题描述:
我目前正在研究一个多维数据集求解器,它使用宽度优先搜索来寻找2x2x2 rubiks多维数据集求解器的最短解决方案。事情是,在搜索中有重复的位置被击中,我的目标是知道我有多少人,并在稍后“修剪”出来(我知道如何避免重复,但与本文无关) 。这是它应该看起来像 获取未被覆盖的equals方法使用hashCode
这是从旧版本的代码与hashCode和等效,但我试图让新版本使用它。我认为这是因为在旧版本中,我会重写equals和hashCode,但在新版本中我似乎无法这样做,因为我不再比较对象,而是数组(这是猜测)。由于这个原因,当前版本不会重复复制。它说没有重复,但这是不正确的。
这里是什么的hashCode和equals是像老版本检测重复。
private Cube() {
cube = new int[][] {
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 2, 2, 2, 2 },
{ 3, 3, 3, 3 },
{ 4, 4, 4, 4 },
{ 5, 5, 5, 5 }
};
cube = scanCube(cube);
cube = print_cube(cube);
}
private Cube(Cube other) {
cube = new int[other.cube.length][];
for (int i = 0; i < other.cube.length; i++) {
cube[i] = Arrays.copyOf(other.cube[i], other.cube[i].length);
}
}
public boolean isSolved() {
for (int i = 0; i < cube.length; i++) {
for (int k = 1; k < cube[i].length; k++) {
if (cube[i][0] != cube[i][k]) {
return false;
}
}
}
return true;
}
@Override
public boolean equals(Object other) {
return other instanceof Cube && Arrays.deepEquals(((Cube) other).cube, cube);
}
@Override
public int hashCode() {
return Arrays.deepHashCode(cube);
}`
这是当前版本。
public static void main(String[] args) {
int[][] cube = new int[][] {
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 2, 2, 2, 2 },
{ 3, 3, 3, 3 },
{ 4, 4, 4, 4 },
{ 5, 5, 5, 5 }
};
cube = scanCube(cube);
cube = print_cube(cube);
solve(cube);
}
private static boolean isSolved(int [][] cube) {
for (int i = 0; i < cube.length; i++) {
for (int k = 1; k < cube[i].length; k++) {
if (cube[i][0] != cube[i][k]) {
return false;
}
}
}
return true;
}
public static int[][] copyCube(int [][] cube){
int [][] copy = new int [6][4];
for(int i = 0; i < 6; i++){
copy[i] = cube[i].clone();
}
return copy;
}
public static boolean equals(int[][] other, int[][] cube) {
return Arrays.deepEquals(other, cube);
}
public int hashCode(int [][] cube) {
return Arrays.deepHashCode(cube);
}
在搜索方法是确定重复的地方。这是旧的代码。
static public void solve(Cube c) {
Set<Cube> cubesFound = new HashSet<Cube>();
cubesFound.add(c);
Stack<Cube> s = new Stack<Cube>();
s.push(c);
Set<Stack<Cube>> initialPaths = new HashSet<Stack<Cube>>();
initialPaths.add(s);
solve(initialPaths, cubesFound);
}
static public void solve(Set<Stack<Cube>> livePaths, Set<Cube> cubesFoundSoFar) {
System.out.println("livePaths size:" + livePaths.size());
int numDupes = 0;
Set<Stack<Cube>> newLivePaths = new HashSet<Stack<Cube>>();
for (Stack<Cube> currentPath : livePaths) {
Set<Cube> nextStates = currentPath.peek().getNextStates();
for (Cube next : nextStates) {
if (currentPath.size() > 1 && next.isSolved()) {
currentPath.push(next);
System.out.println("Path length:" + currentPath.size());
System.out.println("Path:" + currentPath);
System.exit(0);
} else if (!cubesFoundSoFar.contains(next)) {
Stack<Cube> newCurrentPath = new Stack<Cube>();
newCurrentPath.addAll(currentPath);
newCurrentPath.push(next);
newLivePaths.add(newCurrentPath);
cubesFoundSoFar.add(next);
} else {
numDupes += 1;
}
}
}
System.out.println("Duplicates found " + numDupes + ".");
solve(newLivePaths, cubesFoundSoFar);
}
而新的。
static private void solve(int[][] cube) {
int[][][] s = new int[12][6][4];
s[0] = cube;
Set<int[][][]> initialPaths = new HashSet<int[][][]>();
initialPaths.add(s);
Set<int[][]> cubesFound = new HashSet<int[][]>();
cubesFound.add(cube);
solve(initialPaths, cubesFound, 1);
}
static private void solve(Set<int[][][]> livePaths,Set<int[][]> cubesFoundSoFar, int iterationCount) {
System.out.println("livePaths size:" + livePaths.size());
Set<int[][][]> newLivePaths = new HashSet<int[][][]>();
int counter = 0;
int recordDepth = 0;
int duplicates = 0;
for(int[][][] currentPath : livePaths) {
Set<int [][]> nextStates = getNextStates(currentPath[iterationCount-1]);
for (int[][] next : nextStates) {
if (isSolved(next)) {
currentPath[iterationCount] = next;
int maxSteps = -1;
System.out.println("Path:");
for(int i = 0; i < currentPath.length; i++) {
if(currentPath[i] != null) {
maxSteps = i;
System.out.println(toString(currentPath[i]));
}else {
break;
}
}
System.out.println("Path length:" + maxSteps);
System.exit(0);
} else if(!cubesFoundSoFar.contains(next)){
int[][][] newCurrentPath = new int[12][6][4];
newCurrentPath = currentPath.clone();
newCurrentPath[iterationCount] = next;
newLivePaths.add(newCurrentPath);
counter ++;
cubesFoundSoFar.add(next);
} else {
duplicates += 1;
}
}
}
//System.out.println(" Set.size(): "+newLivePaths.size());
String storeStates = "positions.txt";
try {
PrintWriter outputStream = new PrintWriter(storeStates);
outputStream.println(storeStates);
for(int[][][] s:newLivePaths) {
outputStream.println(toString(s[iterationCount]));
}
outputStream.close();
} catch (FileNotFoundException e) {
System.err.println("Fatal: could not open cache file for cube positions. exiting.");
e.printStackTrace();
System.exit(1);
}
System.out.println("Duplicates found "+ duplicates + ".");
solve(newLivePaths, cubesFoundSoFar, iterationCount+1);
}
答
您还没有覆盖在你的第二个代码equals(Object)
方法,但 Set.contains(Object)
使用equals
比较的元素。由于立方体中没有,因此使用Object
之一。这不会比较内容,它只是测试对象是否是相同的实例(相同的内存位置)。
这里contains
相关部分:
...更正式地说,返回true当且仅当该组包含的元素e(O == NULLé== NULL:Ø .equals(e))。 ...
你可能喜欢的东西添加到第二代码:
@Override
public boolean equals(Object other) {
if (other instanceof Cube)
return equals(cube, ((Cube) other).cube);
else
return false;
}
@Override
public int hashCode() {
return hashCode(cube);
}
所以,如果我知道,你问为什么你重复检测方法是行不通的,对吗?那个方法在哪里?如果您不发布,我们可以提供什么帮助? –
是的,它不是在新版本中工作,我会将代码发布到旧版和新版的代码中。 @JBNizet – cuber
@JBNizet更新了它 – cuber