5

ヒューリスティックのすべての組み合わせを試して、要素の抽出と挿入を実行するためにリンクされたリストを使用したいと思います。このタイプの操作では、連結リストの方が効率的です。可能なすべての抽出/挿入のペアを試したいので、リストに対して 2 つの異なる反復子を使用しました。これにより、「ConcurrentModificationException」が発生します。そもそもリストを使用する目的全体が無効になるため、毎回リストを再走査することなく、この操作を効率的に実行するにはどうすればよいでしょうか?

コードの関連部分は次のとおりです。

ListIterator<Integer> it1 = data.listIterator();
ListIterator<Integer> it2;

while(it1.hasNext()) {
    int i = it1.next();
    it2 = data.listIterator();

    while(it2.hasNext()) {
        if (i == it2.next()) continue; // continue right away when the indexes are equal
        it1.remove();
        it2.add(i);
        if (length() < best)
            return true;
        }

    // when the swap is not better/consistent
    it2.remove();
    it1.add(i);
}
return false;

ありがとう

4

3 に答える 3

1

LinkedList で複数のイテレータを同時に使用することはできませんが、CopyOnWriteArrayList

これを試して:

List<Integer> safeData = new CopyOnWriteArrayList(date);
// your code, but working with safeData rather than data
于 2012-11-15T14:44:08.050 に答える
1

私の理解が正しければ、リストを操作するための複数の反復子を提供するデータ構造を探します。これは、元の java.util.LinkedList では技術的に困難です。これは、現在のインデックスのハウスキーピングを行うためです。これは、他の反復子によるリスト内の不明な位置での並列変更がない場合にのみ効率的な方法で可能です。ただし、このハウスキーピングを行わず、複数の反復子による追加/削除をサポートする単純な LinkedList を簡単に実装できます。次に、反復子はリスト内の位置を知りませんが、気にしないに違いありません。次のようなものを使用してください:

public class MyList<T> {
private MyNode<T> first = null, last = null;

public MyNode<T> getFirst() {
    return first;
}

public MyNode<T> getLast() {
    return last;
}

public boolean contains(MyNode<T> n) {
    return n.list == this;
}

/**
 * If beforeMe is null, toInsert is inserted at the end of the list.
 * @return inserted node
 */
public void insertBefore(MyNode<T> beforeMe, MyNode<T> newNode) {
    if (newNode == null) {
        throw new IllegalArgumentException("toInsert must not be null!");
    }

    if (newNode.list != null) {
        throw new IllegalArgumentException("This node is already in the list " + newNode.list);
    }

    if (beforeMe == null) {
        if (last == null) {
            newNode.prev = newNode.next = null;
            first = last = newNode;
        } else {
            last.next = newNode;
            newNode.prev = last;
            newNode.next = null;
            last = newNode;
        }
    } else {
        newNode.prev = beforeMe.prev;
        newNode.next = beforeMe;

        if (beforeMe.prev != null) {
            beforeMe.prev.next = newNode;
        } else {
            first = newNode;
        }

        beforeMe.prev = newNode;
    }

    newNode.list = this;
}

/**
 * If beforeMe is null, t is inserted at the end of the list.
 * @return inserted node
 */
public MyNode<T> insertBefore(MyNode<T> beforeMe, T t) {
    MyNode<T> newNode = new MyNode<T>(t);
    insertBefore(beforeMe, newNode);
    return newNode;
}

public void remove(MyNode<T> n) {
    if (n == null || n.list != this) {
        throw new IllegalArgumentException("Node is not in the list!");
    }

    if (n.prev != null) {
        n.prev.next = n.next;
    } else {
        first = n.next;
    }

    if (n.next != null) {
        n.next.prev = n.prev;
    } else {
        last = n.prev;
    }

    n.prev = n.next = null;
    n.list = null;
}}

public class MyNode<T> {

private T t;
/**
 * written only by MyList
 */
MyNode<T> prev = null;
/**
 * written only by MyList
 */
MyNode<T> next = null;
/**
 * written only by MyList
 */
MyList<T> list = null;

public T get() {
    return t;
}

public void set(T t) {
    this.t = t;
}

public MyNode<T> previous() {
    return prev;
}

public MyNode<T> next() {
    return next;
}

public MyList<T> list() {
    return list;
}

/**
 * called only by MyList.
 * @param t
 */
MyNode(T t) {
    this.t = t;
}}
于 2013-07-25T13:03:39.550 に答える
0

読み取り操作のみを実行している場合は、LIST で任意の数の反復子を使用できます。ここで削除/追加を行っているため、現在発生しているように ConcurrentModificationException が発生するため、2 つの異なる反復子で同じリストを使用することはできません。

何を達成したいですか?おそらく、人々はさまざまなオプションであなたを助けることができます.

于 2012-11-15T14:23:59.763 に答える