[英]How to randomize ArrayList without using Collections.swap()?
I was asked to create a method that randomly rearranges my list which contains arrays.我被要求创建一个随机重新排列包含数组的列表的方法。 The list contains multiple persons and their names and surnames.
该列表包含多个人及其姓名。 My question is how do I move a person (array containing two elements name and surname inside the list) to a different index without using the method swap()?
我的问题是如何在不使用 swap() 方法的情况下将一个人(列表中包含两个元素 name 和 surname 的数组)移动到不同的索引? Because our list does not support that method.
因为我们的列表不支持该方法。 Sadly we do not use the "official" list and have our own one coded like this:
遗憾的是,我们不使用“官方”列表,而是使用我们自己的代码如下:
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;
}
}
This is my version of the wanted method it should randomly rearrange the list by swapping objects multiple times but it apparently does not work.这是我想要的方法的版本,它应该通过多次交换对象来随机重新排列列表,但它显然不起作用。
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);
}
}
I would be very glad if somebody could help me find a way to swap elements inside of my list so that I can finally get my method to randomly rearrange the list.如果有人能帮我找到一种方法来交换我的列表中的元素,我会很高兴,这样我就可以最终获得随机重新排列列表的方法。
Thank you for every answer!谢谢你的每一个回答! :)
:)
I would suggest firstly converting your list to an array, so you have O(1)
random access, then shuffle this array and after that replace values in your list.我建议首先将您的列表转换为数组,这样您就可以进行
O(1)
随机访问,然后对这个数组进行洗牌,然后替换列表中的值。
Here is a code这是一个代码
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();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.