Java 我的功能似乎是编辑多个对象
在我的数独Android应用程序中,我有一个解算函数来解一个数独难题(一个CellField对象)。但是,由于某种原因,当我克隆一个CellField对象并对克隆对象调用solve方法时,solve方法会同时解决两个CellField对象,但我只希望它解决克隆的CellField对象,而不是原始对象。有什么建议吗?谢谢 在这里,我克隆CellField对象(克隆名为temp),并调用solve方法Java 我的功能似乎是编辑多个对象,java,android,object,Java,Android,Object,在我的数独Android应用程序中,我有一个解算函数来解一个数独难题(一个CellField对象)。但是,由于某种原因,当我克隆一个CellField对象并对克隆对象调用solve方法时,solve方法会同时解决两个CellField对象,但我只希望它解决克隆的CellField对象,而不是原始对象。有什么建议吗?谢谢 在这里,我克隆CellField对象(克隆名为temp),并调用solve方法 CellField temp = null; try { temp = board.cf.c
CellField temp = null;
try {
temp = board.cf.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
int x = randInt(0,8);
int y = randInt(0,8);
while (!temp.getCell(y,x).isEditable && board.cf.getCell(y,x).getValue() == 0) {
x = randInt(0,8);
y = randInt(0,8);
}
SudokuSolver solver = new SudokuSolver();
solver.solve(temp);
这是我的求解方法和SudokuSolver类
package com.example.czhou.myapplication2;
import java.util.*;
public class SudokuSolver {
static boolean retry;
public static int randInt(ArrayList<Integer> candidates) {
int min = 0;
int max = candidates.size() - 1;
//inclusive
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
int result = candidates.get(randomNum);
candidates.remove(randomNum);
return result;
}
public boolean solve(CellField field) {
// write your code here
boolean isValid = true;
Set<Integer> toRemove = new HashSet<>();
int i;
int j;
for (int k = 0; k < 9; k++) {
for (int l = 0; l < 9; l++) {
field.getCell(k, l).restAlt();
if (field.getCell(k, l).alt.indexOf(field.getCell(k, l).getValue()) != -1) {
field.getCell(k, l).alt.remove(field.getCell(k, l).alt.indexOf(field.getCell(k, l).getValue()));
}
}
}
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
if (field.getCell(i,j).getValue() == 0 && field.getCell(i,j).alt.size() == 0){
field.getCell(i,j).restAlt();
}
if (field.getCell(i, j).isEditable) {
toRemove.clear();
for (int k = 0; k < 9; k++) {
toRemove.add(field.getCell(k, j).getValue());
}
toRemove.addAll(field.getSectorCandidates(i, j));
for (int k = 0; k < 9; k++) {
toRemove.add(field.getCell(i, k).getValue());
}
toRemove.removeAll(Collections.singleton(0));
field.getCell(i, j).alt.removeAll(toRemove);
if (toRemove.size() == 9 || field.getCell(i, j).alt.size() == 0) {
//When there no candidates are available
//in the current cell, come here
//toRemove.clear();
Cell cell;
boolean stop = false;
backtrack:
for (int k = j; !stop; k--) {
if (k == -1) {
if (i != 0) {
--i;
} else {
break;
}
k = 8;
}
j = k;
// Scan for previous cells have alternative candidates
cell = field.getCell(i, k);
if (cell.alt.size() > 0 && cell.isEditable) {
//bookmark the original cell
//int nextCell = k+1;
// If found a cell set value as first alternative
cell.setValue(cell.alt.get(0));
break backtrack;
} else if (cell.isEditable){
// if no alternatives set cell to 0 and continue backwards
cell.setValue(0);
}
}
} else {
field.getCell(i, j).setValue(randInt(field.getCell(i, j).alt));
}
}
}
}
// for (int m = 0; m < 9; m++) {
// for (int l = 0; l < 9; l++) {
// if (l == 0) {
// System.out.println();
// }
// System.out.print(field.getCell(m, l).getValue());
// }
// }
// System.out.println();
// System.out.println("================");
return isValid;
}
}
package com.example.czhou.myapplication2;
导入java.util.*;
公共级数独行者{
静态布尔重试;
公共静态int randInt(ArrayList候选){
int min=0;
int max=candidates.size()-1;
//包容的
Random rand=新的Random();
int randomNum=rand.nextInt((最大-最小)+1)+min;
int result=candidates.get(randomNum);
删除(随机数);
返回结果;
}
公共布尔解算(CellField){
//在这里编写代码
布尔值isValid=true;
Set toRemove=newhashset();
int i;
int j;
对于(int k=0;k<9;k++){
对于(int l=0;l<9;l++){
field.getCell(k,l.restAlt();
if(field.getCell(k,l).alt.indexOf(field.getCell(k,l).getValue())!=-1){
field.getCell(k,l).alt.remove(field.getCell(k,l).alt.indexOf(field.getCell(k,l).getValue());
}
}
}
对于(i=0;i<9;i++){
对于(j=0;j<9;j++){
if(field.getCell(i,j).getValue()=0&&field.getCell(i,j).alt.size()=0){
field.getCell(i,j).restAlt();
}
if(field.getCell(i,j).isEditable){
toRemove.clear();
对于(int k=0;k<9;k++){
添加(field.getCell(k,j.getValue());
}
toRemove.addAll(field.getSectorCandidates(i,j));
对于(int k=0;k<9;k++){
添加(field.getCell(i,k.getValue());
}
toRemove.removeAll(Collections.singleton(0));
field.getCell(i,j).alt.removeAll(toRemove);
if(toRemove.size()=9 | | field.getCell(i,j).alt.size()=0){
//当没有候选人时
//在当前的牢房里,过来
//toRemove.clear();
细胞;
布尔停止=假;
回溯:
对于(int k=j;!stop;k--){
如果(k==-1){
如果(i!=0){
--一,;
}否则{
打破
}
k=8;
}
j=k;
//扫描以前的单元格是否有其他候选单元格
cell=field.getCell(i,k);
if(cell.alt.size()>0&&cell.isEditable){
//为原始单元格添加书签
//int nextCell=k+1;
//如果找到一个单元格,则将其设置为第一个备选值
cell.setValue(cell.alt.get(0));
打破倒退;
}else if(cell.isEditable){
//如果没有备选方案,则将单元格设置为0并向后继续
cell.setValue(0);
}
}
}否则{
getCell(i,j).setValue(randInt(field.getCell(i,j).alt));
}
}
}
}
//对于(int m=0;m<9;m++){
//对于(int l=0;l<9;l++){
//如果(l==0){
//System.out.println();
// }
//System.out.print(field.getCell(m,l.getValue());
// }
// }
//System.out.println();
//System.out.println(“============================”);
返回有效;
}
}
这是我的CellField课程
package com.example.czhou.myapplication2;
import android.util.Log;
import java.io.Serializable;
import java.util.*;
import java.util.regex.Matcher;
public class CellField implements Cloneable{
protected Cell[][] field = new Cell[9][9];
public CharSequence timeElapsed = "00:00";
public CellField() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
field[i][j] = new Cell();
}
}
}
public CellField(CellField another) {
List<Cell[]> cellfield = Arrays.asList(another.field);
this.field = (Cell[][]) cellfield.toArray();
}
public CellField clone() throws CloneNotSupportedException {
return (CellField)super.clone();
}
}
package com.example.czhou.myapplication2;
导入android.util.Log;
导入java.io.Serializable;
导入java.util.*;
导入java.util.regex.Matcher;
公共类CellField实现可克隆{
受保护单元[]字段=新单元[9][9];
public CharSequence timeappeased=“00:00”;
公共CellField(){
对于(int i=0;i<9;i++){
对于(int j=0;j<9;j++){
字段[i][j]=新单元格();
}
}
}
公共小区域(另一个小区域){
List cellfield=Arrays.asList(另一个.field);
this.field=(Cell[]])cellfield.toArray();
}
public CellField clone()抛出CloneNotSupportedException{
return(CellField)super.clone();
}
}
问题在于您的克隆方法,正如@ρ∑ρѕρє所说的,您应该进行深度复制。因为现在您正在返回相同的引用。试着这样做:
public CellField clone() throws CloneNotSupportedException {
CellField clone = new CellField();
clone.field = this.field;
clone.timeElapsed = this.timeElapsed;
return clone;
}
这是一个浅拷贝与深拷贝的问题
class SomeClass implements Cloneable {
// This is the problematic field. It doesn't get cloned the way you think it is.
public Integer[] field = new Integer[5];
public SomeClass clone() throws CloneNotSupportedException {
return (SomeClass) super.clone();
}
}
public class HelloWorld {
public static void main(String []args){
SomeClass first = new SomeClass();
SomeClass second = null;
try {
second = first.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(first.field);
System.out.println(second.field);
// Their addresses in memory are the same
// Modifying one would modify the other
// first.field == second.field -> true
}
}
在上面的示例中,我将类的一个实例克隆到另一个实例中,但它们共享同一个字段。改变类的第一个实例的字段将直接影响类的第二个实例中的字段,因为它们都拥有对它的引用
您可以定义一个复制构造函数并自行执行克隆,而不是使用Cloneable
更多详细信息,请访问@Christ