Java递归,用对象调用它 - 如何复制对象?

发布于 2024-09-08 09:32:09 字数 2736 浏览 2 评论 0原文

旧的价值/参考的东西。我收到 ConcurrentModificationException 对于布朗-克博什的改编。

public int[] bk(ArrayList<Integer> R, ArrayList<Integer> P, ArrayList<Integer> X) {
    int count[] = new int[n];
    int u=0, c = 0;

    ArrayList<Integer> tempPX = new ArrayList<Integer>();
    ArrayList<Integer> newP = P;
    ArrayList<Integer> newX = X;
    ArrayList<Integer> newR = R;

    if (P.isEmpty() && X.isEmpty()) {
        count[R.size()]++;
    } else {

        u = 0; c = 0; // find vertex with largest degree            
        tempPX.addAll(P); tempPX.addAll(X); // P ⋃ X
        for (Integer v : tempPX) {            
            if (neighbours[v].size() > neighbours[u].size()) {
                u = c; 
            }
            c++;
        } 

        P.removeAll(neighbours[u]); // P \ neighbours[u]
        for (Integer v : newP) {

            newR.add(v); // R ⋃ v

            newP.retainAll(neighbours[v]); // P â‹‚ neighbours[v]

            newX.retainAll(neighbours[v]); // X â‹‚ neighbours[v]

            bk(newR, newP, newX); 

            P.remove(v); // removing object
            X.add(v); // X ⋃ v
        }

    }

    return count;
}

异常发生在 for (Integer v : newP) 行以及其中的递归调用处。 我需要 P.removeAll(neighbours[u]);然后循环遍历结果列表,在注释中执行操作,并在递归调用中传递副本,这样它就不会抱怨,并且工作不会传递引用并继续修改同一对象 P/X/R 。那么我如何以及何时复制它们?这些第一行..我正在复制参考资料不是我... (是的,我知道我“修改”newP,然后循环旧的P,它们只是指向看起来相同的对象)

---阅读回复后的新代码-

   public int[] bk(List<Integer> r, List<Integer> p, List<Integer> x) {
    int count[] = new int[n];
    int u = 1;

    List<Integer> tempPX = new ArrayList<Integer>();
    List<Integer> newR, newP, newX;

    if (p.isEmpty() && x.isEmpty()) {
        count[r.size()]++;
    } else {

        // find vertex with largest degree in P U X        
        tempPX.addAll(p); 
        tempPX.addAll(x);
        for (Integer v : tempPX) {            
            if (neighbours[v].size() > neighbours[u].size()) {
                u = v; 
            }
        } 

        p.removeAll(neighbours[u]);  // P \ neighbours[u]
        newP = new ArrayList<Integer>(p); 
        for (Integer v : newP) {

            r.add(v); // R U  v
            newR = new ArrayList<Integer>(r);

            p.retainAll(neighbours[v]);  // P /\ neighbours[v]
            newP = new ArrayList<Integer>(p);

            x.retainAll(neighbours[v]); // X /\ neighbours[v]
            newX = new ArrayList<Integer>(x);

            bk(newR, newP, newX); 

            p.remove(v); // removing object
            x.add(v); // X U v
        }

    }

    return count;
}

The old value/reference things. Im getting ConcurrentModificationException
for this adaptation of the Bron-Kerbosch.

public int[] bk(ArrayList<Integer> R, ArrayList<Integer> P, ArrayList<Integer> X) {
    int count[] = new int[n];
    int u=0, c = 0;

    ArrayList<Integer> tempPX = new ArrayList<Integer>();
    ArrayList<Integer> newP = P;
    ArrayList<Integer> newX = X;
    ArrayList<Integer> newR = R;

    if (P.isEmpty() && X.isEmpty()) {
        count[R.size()]++;
    } else {

        u = 0; c = 0; // find vertex with largest degree            
        tempPX.addAll(P); tempPX.addAll(X); // P ⋃ X
        for (Integer v : tempPX) {            
            if (neighbours[v].size() > neighbours[u].size()) {
                u = c; 
            }
            c++;
        } 

        P.removeAll(neighbours[u]); // P \ neighbours[u]
        for (Integer v : newP) {

            newR.add(v); // R ⋃ v

            newP.retainAll(neighbours[v]); // P â‹‚ neighbours[v]

            newX.retainAll(neighbours[v]); // X â‹‚ neighbours[v]

            bk(newR, newP, newX); 

            P.remove(v); // removing object
            X.add(v); // X ⋃ v
        }

    }

    return count;
}

The exception occurs at line for (Integer v : newP), and the recursive call in there.
I need to P.removeAll(neighbours[u]); then loop over that resulting list, inside doing the things in the comments, AND PASS COPIES in the recursive call so it wont complain and work not pass the references and keep modifying the same object P/X/R. So how and WHEN do i copy them?? Those first lines.. I'm making copies of the references aren't i...
(yes i know i "modify" newP then loop over the old P, they just point to the same object it seems)

--- new code after reading the replies -

   public int[] bk(List<Integer> r, List<Integer> p, List<Integer> x) {
    int count[] = new int[n];
    int u = 1;

    List<Integer> tempPX = new ArrayList<Integer>();
    List<Integer> newR, newP, newX;

    if (p.isEmpty() && x.isEmpty()) {
        count[r.size()]++;
    } else {

        // find vertex with largest degree in P U X        
        tempPX.addAll(p); 
        tempPX.addAll(x);
        for (Integer v : tempPX) {            
            if (neighbours[v].size() > neighbours[u].size()) {
                u = v; 
            }
        } 

        p.removeAll(neighbours[u]);  // P \ neighbours[u]
        newP = new ArrayList<Integer>(p); 
        for (Integer v : newP) {

            r.add(v); // R U  v
            newR = new ArrayList<Integer>(r);

            p.retainAll(neighbours[v]);  // P /\ neighbours[v]
            newP = new ArrayList<Integer>(p);

            x.retainAll(neighbours[v]); // X /\ neighbours[v]
            newX = new ArrayList<Integer>(x);

            bk(newR, newP, newX); 

            p.remove(v); // removing object
            x.add(v); // X U v
        }

    }

    return count;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吻安 2024-09-15 09:32:09

正如您所确定的,您正在复制参考,而不是列表。您需要使用旧列表中的条目实例化一个新的 ArrayList 对象。

例如

List<Integer> newList = new ArrayList<Integer>(oldList);

,这显式地创建了一个包含对相同元素的引用的新对象。

请注意,我传递了对接口 List 的引用,而不是实现 - 通常是很好的做法,因为您不会在整个代码库中公开实现。

As you've identified, you're copying the reference, not the list. You need to instantiate a new ArrayList object with the entries in the old list.

e.g.

List<Integer> newList = new ArrayList<Integer>(oldList);

So this explicitly creates a new object containing references to the same elements.

Note as an aside that I pass around a reference to the interface List rather than the implementation - generally good practise since you're not exposing implementation throughout the codebase.

深巷少女 2024-09-15 09:32:09

ArrayList newP = P;

这只会创建对同一 ArrayList 的第二个引用。要复制数组列表,请使用

ArrayList newP = new ArrayList(P);

ArrayList newP = P;

This only creates a second reference to the same ArrayList. To copy the arraylist use

ArrayList newP = new ArrayList(P);

烧了回忆取暖 2024-09-15 09:32:09

你的第一个 &&检查是多余的,最初检查是与 X 参数一起进行的?

另外,您在 else 块开头的 for 循环没有任何意义,您想在那里做什么?问题是,您同时使用了计数器 (c) 和 tempPX 列表 (v) 的内容。您使用 v 进行检查,但使用 c 作为赋值。结果完全取决于数据排序,并且不会产生任何有意义的结果。

通常,您会使用其中之一,并在检查和作业中都使用它。

if (p.isEmpty() && p.isEmpty()) {
  count[r.size()]++;
} else {
  u = 0; c = 0; // find vertex with largest degree
  tempPX.addAll(p); tempPX.addAll(x); // P U X
  for (Integer v : tempPX) {
    if (neighbours[v].size() > neighbours[u].size()) {
      u = c; 
    }
    c++;
  }

您的目标要么是在 temppx 列表中找到具有最大数量邻居的索引(删除 c 变量和 c++ 行,在赋值中使用 v),要么只是找到具有最大邻居数量的索引对索引没有任何限制的邻居数量,在这种情况下,您将使用像这样的 for 循环:

for (int c = 0; c < neighbours.size(); ++c)

并删除任何提及 temppx 列表的内容。我的猜测是你试图做第一个案例。

Your first && check is redundant, originally the check was with the X argument?

Also, your for loop at the start of the else block doesn't make any sense, what are you trying to do there? The thing is that you are both using a counter (c) and the contents of the tempPX list (v). You use v to do the check but c as the assignment. The result is totally dependent on data ordering and doesn't produce anything meaningful.

Normally you'd use one or the other and use it both in the check and the assignment.

if (p.isEmpty() && p.isEmpty()) {
  count[r.size()]++;
} else {
  u = 0; c = 0; // find vertex with largest degree
  tempPX.addAll(p); tempPX.addAll(x); // P U X
  for (Integer v : tempPX) {
    if (neighbours[v].size() > neighbours[u].size()) {
      u = c; 
    }
    c++;
  }

Either your goal is to find the index in the temppx list with the largest amount of neighbours (drop the c variable and the c++ line, use v in the assignment) OR to just find the index with the largest amount of neighbours without any restriction on the index, in that case you would use a for loop like this:

for (int c = 0; c < neighbours.size(); ++c)

and drop any mention of the temppx list. My guess is your trying to do the first case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文