Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无重复的随机数序列_Java - Fatal编程技术网

Java 无重复的随机数序列

Java 无重复的随机数序列,java,Java,我正在尝试在我的游戏服务器上做一个pvp事件,它使用3个区域随机进行。我使用以下代码,但总是返回值1和2,并重复。我需要一些像这样的序列,例如:3-2-1-2-1-3,或者不重复相同数字的序列 int random = Rnd.get(1, 3); if (random == 1) { setstartedpvpzone1(true); } if (random == 2) { setstartedpvpzone2(true); } if (random == 3) {

我正在尝试在我的游戏服务器上做一个pvp事件,它使用3个区域随机进行。我使用以下代码,但总是返回值1和2,并重复。我需要一些像这样的序列,例如:3-2-1-2-1-3,或者不重复相同数字的序列

int random = Rnd.get(1, 3);

if (random == 1)
{
    setstartedpvpzone1(true);
}

if (random == 2)
{
    setstartedpvpzone2(true);
}

if (random == 3)
{
    setstartedpvpzone3(true);
}
这是我在rnd中得到的:

public final class Rnd
{
    /**
     * This class extends {@link java.util.Random} but do not compare and store atomically.<br>
     * Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
     * This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
     * @author Forsaiken
     * @see java.util.Random
     */
    public static final class NonAtomicRandom extends Random
    {
        private static final long serialVersionUID = 1L;
        private volatile long _seed;

        public NonAtomicRandom()
        {
            this(++SEED_UNIQUIFIER + System.nanoTime());
        }

        public NonAtomicRandom(final long seed)
        {
            setSeed(seed);
        }

        @Override
        public final int next(final int bits)
        {
            return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
        }

        @Override
        public final void setSeed(final long seed)
        {
            _seed = (seed ^ MULTIPLIER) & MASK;
        }
    }

此代码从不重复任何数字,例如,如果您有1,2,3,则可以得到4个数字的随机序列,例如2,1,3

创建一个包含您需要的所有数字的数组

   int[] a = {1, 2, 3};
然后选择随机项目

   for (int i=0; i<a.length; i++){
       int random = Rnd.get(0, a.length);
       //remove the selected item from the array
       ArrayUtils.removeElement(a, random);

       if (random == 1) {
            setstartedpvpzone1(true);
       } else if (random == 2) {
            setstartedpvpzone2(true);
       } else if (random == 3) {
            setstartedpvpzone3(true);
       }
    }

对于(int i=0;i[未测试]它可能包含一些语法错误,因为我不是Java程序员

    int a=0,b=0;
    while(true)
   {
        int random = Rnd.get(1, 3);
        if(!(a==random or b==random))
        {
            a=b;
            b=random;
            break;
        }
   }

if (random == 1)
{
    setstartedpvpzone1(true);
}

if (random == 2)
{
    setstartedpvpzone2(true);
}

if (random == 3)
{
    setstartedpvpzone3(true);
}

如果您要查找的只是一个随机数,而该随机数不等于上一个返回的随机数,那么解决方案就简单得多:

private Random random = new Random();
private int previousZone = 0;

public int nextZone() {
    int zone;
    do {
        zone = random.nextInt(3) + 1;
    } while (zone == previousZone);

    previousZone = zone; //store last "generated" zone

    return zone;
}

您的问题归结为一个遍历,在这个遍历中,从每个当前区域,您只有两个可能的下一个区域,并且这些选择永远不会改变。因此,我将如何实现它:

public static class EventLocator{
    private int currentZone;
    private Random random;
    private Map<Integer, int[]> locations;
    private static EventLocator instance;

    private EventLocator() {
    }

    public static EventLocator getInstance(){
        if (instance == null) {
            instance = new EventLocator();
        }
        return instance;

    }

    public int getNextZone(){
        if (this.currentZone == 0) {//first time called
            this.random = new Random();
            this.locations = new HashMap<>(3);//graph <currentZone, posibleZones>
            this.locations.put(1, new int[] { 2, 3 });
            this.locations.put(2, new int[] { 1, 3 });
            this.locations.put(3, new int[] { 1, 2 });

            this.currentZone = this.random.nextInt(3) + 1;// to 1-based Zones
            return currentZone;
        }
        int[] possibleZones = this.locations.get(this.currentZone);
        int randomIndex = this.random.nextInt(2);//0 or 1 index
        this.currentZone = possibleZones[randomIndex];
        return this.currentZone;
    }
}
private boolean\u lastevent1=false;
公共布尔lastevent1()
{
返回_lastevent1;
}
public void setlastevent1(布尔值)
{
_lastevent1=val;
}
私有布尔值_lastevent2=false;
公共布尔lastevent2()
{
返回_lastevent2;
}
public void setlastevent2(布尔值)
{
_lastevent2=val;
}
私有布尔值_lastevent3=false;
公共布尔lastevent3()
{
返回_lastevent3;
}
public void setlastevent3(布尔值)
{
_lastevent3=val;

}
随机数库是什么的可能重复
Rnd
?这似乎不是Java标准的
random
库。无论如何,我怀疑传递给
get
的结束值是独占的,因此
get(1,3)
意味着给我一个大于或等于1但严格小于3的值。如果是这样,更改为
get(1,4)
应该可以做到这一点。请定义“永远不要重复相同的数字”假设您的
3-2-1-2-1-3
示例显示了所有三个数字的重复。您的意思是它应该在重新开始之前运行一个完整的非重复数字序列吗?或者您的意思是不允许相同的数字紧挨着出现?或者其他什么?我每次只需要一个来自12或3的数字,因为我使用此数字以随机方式启动事件,并且决不能同时重复2次。数字1对应于区域1、数字2区域2、数字3区域3,那么每次事件启动时我都需要新区域。我在这一行中得到错误ArrayUtils.removeElement(a,random)错误显示:方法removeElement(int[],int)类型ArrayUtils未定义。我可以从我的源代码ArrayUtils使用它。删除(数组,值),但与代码不匹配。感谢您的帮助..错误:类型ArrayUtils中的方法remove(T[],T)不适用于参数(int[],int)正如我在javadocs removeElement中看到的那样,removeElement是正确的方法是的,你是对的很好,问题是我的错误导入了错误,但是你的代码返回给我这样的结果:2-3-2-1-2-3-3-3-3-2-1-2-3-3-1-1,无论如何,谢谢你尝试帮助我,出于某种原因,有时会重复这3次。谢谢你的帮助..我正在测试你的代码现在,您好,我测试了您的代码,它返回如下数字的顺序:3-2-2-3-1-2-2-2-1-3-2-1-2-2始终重复数字2,然后无效,因为正在重复数字,无论如何,感谢您尝试帮助我。可能是在一个函数中的代码,您多次调用该代码,导致a和b的值每次都赋值为零;a和b必须是全局variablehello经过测试,这个类返回了一个不同于1-2-3的数字,因为不起作用,谢谢你们的帮助,我仍在尝试修复它,只是3个随机数,无法完成xDa一系列的数字,如1-2-3-1-2-3-1-2-3是有效的。getNextZone()将返回任何区域(1,2或3),没有重复。它是完全随机的。EventLocator EventLocator=EventLocator.getInstance();if(EventLocator.getNextZone()==1){setStartedPvZone1(true);}if(EventLocator.getNextZone()==2){setStartedPvZone2(true);}if(EventLocator.getNextZone()==3){setstartedpvpzone3(true);}我这样使用,有时返回介于123之间的数字,但有时返回否,则系统不工作。调用EventLocator.getInstance().getNextZone()一次,如int-nextZone=EventLocator.getInstance().getNextZone();if(nextZone==1){…}ELSE if(nextZone==2){…}ELSE{…}你好,谢谢你的回答,你的代码返回我0,没有工作。
public static class EventLocator{
    private int currentZone;
    private Random random;
    private Map<Integer, int[]> locations;
    private static EventLocator instance;

    private EventLocator() {
    }

    public static EventLocator getInstance(){
        if (instance == null) {
            instance = new EventLocator();
        }
        return instance;

    }

    public int getNextZone(){
        if (this.currentZone == 0) {//first time called
            this.random = new Random();
            this.locations = new HashMap<>(3);//graph <currentZone, posibleZones>
            this.locations.put(1, new int[] { 2, 3 });
            this.locations.put(2, new int[] { 1, 3 });
            this.locations.put(3, new int[] { 1, 2 });

            this.currentZone = this.random.nextInt(3) + 1;// to 1-based Zones
            return currentZone;
        }
        int[] possibleZones = this.locations.get(this.currentZone);
        int randomIndex = this.random.nextInt(2);//0 or 1 index
        this.currentZone = possibleZones[randomIndex];
        return this.currentZone;
    }
}
EventLocator eventLocator = MyProgram.EventLocator.getInstance();
System.out.println(eventLocator.getNextZone());
System.out.println(eventLocator.getNextZone());