如何在不使用collections.swap()的情况下随机化arraylist?

qlfbtfca  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(432)

我被要求创建一个随机重新排列包含数组的列表的方法。该列表包含多人及其姓名。我的问题是如何在不使用swap()方法的情况下将person(列表中包含两个元素name和姓氏的数组)移动到不同的索引?因为我们的列表不支持这种方法。遗憾的是,我们没有使用“官方”列表,我们自己的列表编码如下:

public class List<ContentType> {  

    private class ListNode {

        private ContentType contentObject;
        private ListNode next;

        private ListNode(ContentType pContent) {
          contentObject = pContent;
          next = null;
        }

        public ContentType getContentObject() {
          return contentObject;
        }

        public void setContentObject(ContentType pContent) {
          contentObject = pContent;
        }

        public ListNode getNextNode() {
          return this.next;
        }

        public void setNextNode(ListNode pNext) {
          this.next = pNext;
        }
    }

    ListNode first;   
    ListNode last;    
    ListNode current;

    public List() {
        first = null;
        last = null;
        current = null;
    }

    public boolean isEmpty() {
        return first == null;
    }

    public boolean hasAccess() {
        return current != null; 
    }

    public void next() {
        if (this.hasAccess()) {
            current = current.getNextNode();
        }
    }

    public void toFirst() {
        if (!isEmpty()) {
            current = first;
        }
    }

    public void toLast() {
        if (!isEmpty()) {
            current = last;
        }
    }

    public ContentType getContent() {
        if (this.hasAccess()) {
            return current.getContentObject();
        } else {
            return null;
        }
    }

    public void setContent(ContentType pContent) {

        if (pContent != null && this.hasAccess()) { 
            current.setContentObject(pContent);
        }
    }

    public void insert(ContentType pContent) {
        if (pContent != null) { 
            if (this.hasAccess()) { 
                ListNode newNode = new ListNode(pContent); 

                if (current != first) { 
                    ListNode previous = this.getPrevious(current);
                    newNode.setNextNode(previous.getNextNode());
                    previous.setNextNode(newNode);
                } else { 
                    newNode.setNextNode(first);
                    first = newNode;
                }
            } else {
                if (this.isEmpty()) {
                    ListNode newNode = new ListNode(pContent); 

                    first = newNode;
                    last = newNode;
                }
            }
        }
    }

    public void append(ContentType pContent) {
        if (pContent != null) {
            if (this.isEmpty()) { 
                this.insert(pContent);
            } else { 
                ListNode newNode = new ListNode(pContent); 

                last.setNextNode(newNode);
                last = newNode;    
            }
        }
    }

    public void concat(List<ContentType> pList) {
        if (pList != this && pList != null && !pList.isEmpty()) { 

            if (this.isEmpty()) { 
                this.first = pList.first;
                this.last = pList.last;
            } else { 
                this.last.setNextNode(pList.first);
                this.last = pList.last;
            }

            pList.first = null;
            pList.last = null;
            pList.current = null;
        }
    }

    public void remove() {
        if (this.hasAccess() && !this.isEmpty()) { 
            if (current == first) {
                first = first.getNextNode();
            } else {
                ListNode previous = this.getPrevious(current);
                if (current == last) {
                    last = previous;
                }
                previous.setNextNode(current.getNextNode());
            }

            ListNode temp = current.getNextNode();
            current.setContentObject(null);
            current.setNextNode(null);
            current = temp;

            if (this.isEmpty()) {
                last = null;
            }
        }
    }

    private ListNode getPrevious(ListNode pNode) {
        if (pNode != null && pNode != first && !this.isEmpty()) {
            ListNode temp = first;
            while (temp != null && temp.getNextNode() != pNode) {
                temp = temp.getNextNode();
            }
            return temp;
        } else {
            return null;
        }
    }

    public int length() {
        int i = 0;
        while(this.hasAccess()) {
            i++;
            next(); 
        }
        return i;
    }
}

这是我想要的方法的版本,它应该通过多次交换对象来随机重新排列列表,但显然不起作用。

public static void shuffleList(final List<String[]> list) {

    int length = list.length();
    Random random = new Random();

    for (int i = 0; i < length; i++) {

        // Swap index
        int swap = i + random.nextInt(length - i);

        // Store temporarily
        String name1 = list.getContent()[0];
        String surname1 = list.getContent()[1];
        String[] temp1 = {mail1, pw1};

        System.out.println(temp1);

        for (int j = 0; j < swap; j++) {
            list.next();
        }

        String name2 = list.getContent()[0];
        String surname2 = list.getContent()[1];
        String[] temp2 = {mail2, pw2};

        // Set the values
        list.setContent(temp1);

        list.toFirst();
        for (int k = 0; k < i; k++) {
            list.next();
        }
        list.setContent(temp2);
    }
}

如果有人能帮我找到一种方法来交换列表中的元素,这样我就可以最终得到随机重新排列列表的方法,我将非常高兴。
谢谢你的回答!:)

nafvub8i

nafvub8i1#

我建议首先将列表转换为数组,因此 O(1) 随机访问,然后洗牌此数组,然后替换列表中的值。
这是一个密码

public class ListUtils {

    /**
     * Shuffles a list, leaving it's pointer on the first element.
     * 
     * @param list list to shuffle
     * @param rnd random number generator
     */
    @SuppressWarnings({"unchecked"})
    public static <T> void shuffleList(List<T> list, Random rnd) {
        Object[] arr = toArray(list);

        for (int i = arr.length; i > 1; --i) {
            swap(arr, i - 1, rnd.nextInt(i));
        }

        list.toFirst();
        for (Object o : arr) {
            list.setContent((T) o);
            list.next();
        }
    }

    private static void swap(Object[] arr, int i, int j) {
        Object temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    private static Object[] toArray(List<?> list) {
        // length is O(n), makes sense to track size on every add, so it will be O(1)
        list.toFirst();
        int size = list.length();
        Object[] result = new Object[size];
        list.toFirst();
        for (int i = 0; i < size; ++i) {
            result[i] = list.getContent();
            list.next();
        }
        return result;
    }

    public static void main(String[] args) {
        List<String> l = new List<>();
        l.append("a");
        l.append("b");
        l.append("c");
        l.append("d");
        shuffleList(l, new Random());
        l.toFirst();
        while (l.hasAccess()) {
            System.out.println(l.getContent());
            l.next();
        }
    }
}

相关问题