简体   繁体   English

从1到100生成随机数

[英]Generating Random Numbers from 1-100

int getnum50()
{ 
  Random rand = new Random(); 
  return (1+rand.nextInt(50)); 
}    
  • You are given a predefined function named getnum50() which returns an integer which is one random number from 1-50. 为您提供了一个名为getnum50()的预定义函数,该函数返回一个整数,该整数是1-50之间的一个随机数。
  • You can call this function as many times as you want but beware that this function is quite resource intensive. 您可以根据需要多次调用此函数,但是请注意,此函数会占用大量资源。
  • You cannot use any other random generator. 您不能使用任何其他随机生成器。 You can NOT change the definition of getnum50() . 您不能更改getnum50()的定义。

Print numbers 1-100 in random order. 以随机顺序打印数字1-100。 (Not 100 random numbers) (不是100个随机数)

Note: 注意:

  • i. 一世。 Every number should be printed exactly once. 每个数字应打印准确一次。
  • ii. ii。 There should be no pattern in the numbers listing. 数字列表中不应有任何模式。 List should be completely random ie, all numbers have equal probability appearing at any place. 列表应该是完全随机的,即所有数字在任何地方出现的可能性均等。
  • iii. iii。 You may call getnum50() any number of time to get random number from 1 to 50 but try to make the code optimised. 您可以多次调用getnum50()来获取1到50之间的随机数,但是请尝试使代码最佳化。
  • iv. iv。 You cannot use any other random generator function except getnum50(). 除getnum50()外,不能使用任何其他随机生成器函数。

I wrote some code which was showing correct output. 我写了一些显示正确输出的代码。

import java.util.Random;

public class RandomInteger{

    int number[]=new int[100];//To store numbers in random order

    public RandomInteger(){
        int n[]=new int[100];//array to store which random numbers are generated
        int off[]={-1,0};//offset to add
        System.out.println("Length of array number100 is:"+number.length);
        System.out.println("Generating  random numbers in the range 1-100:");
        for(int n1=0;n1<number.length;n1++){
            int rnd=off[(getnum50()-1)/50]+(getnum50()*2);
            if(n[rnd-1] == 0){
                n[rnd-1]=1;//to indicate which random number is generated
                number[n1]=rnd;
                System.out.println(number[n1]+" ");
            }
        }
    }
    //end of constructor

    int getnum50(){  
        Random rand = new Random(); 
        return (1+rand.nextInt(50));      
    }

    public static void main(String args[]){
        RandomInteger m= new RandomInteger();
    }
    //end of main()
}
//end of class

While it was accepted in that round, in the next round the interviewer tells me that getnum50() is a costly method and even in best case scenario I have to call it twice for every number generated. 尽管在那一轮中被接受,但在下一轮中,访问员告诉我getnum50()是一种昂贵的方法,即使在最佳情况下,我也必须为生成的每个数字两次调用它。 ie 200 times for 1-100. 即1-100的200倍。 In worst case scenario it would be infinity and tens of thousand in average case. 在最坏的情况下,它将是无穷大,平均情况下为数万。 He asks me to optimize the code so as to significantly improve the average case. 他要求我优化代码,以大大改善平均情况。 I could not answer.So please give me proper answer for the question? 我无法回答。所以请给我适当的答案? How will I optimize my above code?? 我如何优化上面的代码?

One stupid optimization would be be to just realize that since your randomized source is limited to 1-50, you might as well set TWO array positions, eg 一种愚蠢的优化是仅意识到由于您的随机源限制为1-50,因此您最好设置两个数组位置,例如

rand = getnum50();
n[rand] = 1;
n[rand+50] = 1;

Now the array will be slightly "less" random, because every index n is going simply be 1/2 of whatever's at n+50 , but at least you've cut ~half the build array construction time. 现在,该数组将具有“较少”的随机性,因为每个索引n都只是n+50处值的1/2,但至少您将构建数组的构建时间减少了约一半。

I think they want you to produce a shuffle algorithm. 我认为他们希望您产生一种随机播放算法。

In this, you start with an array of exactly 100 numbers ( 1 through 100 in order ), and then on each iteration you shuffle the numbers. 在这种情况下,您将从一个正好为100的数字组成的数组(顺序为1到100)开始,然后在每次迭代中对数字进行混洗。

Do it enough times, and the original array is completely random. 这样做足够的时间,原始数组是完全随机的。

The 50 is a red herring. 50是红鲱鱼。 Use two calls to random50, mod 10. Now you have two digits: tens and ones place. 使用两个对random50,mod 10的调用。现在您有两个数字:十位和一位。 This gives you a random100() function. 这为您提供了random100()函数。

The real killer is the generate-and-check approach. 真正的杀手is是生成和检查方法。 Instead, put the numbers 1-100 into an arraylist, and use your random100 to REMOVE a random index. 而是将数字1-100放入arraylist,然后使用random100删除随机索引。 Now your worst case scenario has 2n calls to random50. 现在,您最坏的情况是有2n次调用random50。 There's a few problems left to solve - overruns - but that's the approach I'd look at. 还有一些问题需要解决-超支-但这就是我要研究的方法。

The reason you are calling the method getnum50() twice is because of this line: 您两次调用方法getnum50()的原因是由于以下这一行:

int rnd = off[(getnum50()-1)/50] + (getnum50()*2);

which seems self-explanatory. 这似乎是不言而喻的。 And the reason your worst case scenario is so bad is because of this block: 最坏的情况如此糟糕的原因是由于以下原因:

if(n[rnd - 1] == 0){
    n[rnd - 1] = 1;          //to indicate which random number is generated
    number[n1] = rnd;
    System.out.println(number[n1] + " ");
}

Depending on how bad your luck is, it could take a very long time to get each value. 根据运气的严重程度,获得每个值可能需要很长时间。 So, best case, you make your two getnum50() calls, which WILL happen the first time, but as you fill up your array, it becomes increasingly less likely. 因此,最好的情况是,您将进行两次getnum50()调用,这将是第一次发生,但是随着您填满数组,这种可能性越来越小。 For 100 numbers, the last number will have a 1% chance of success on the first time, and every time it fails, you make another two calls to getnum50(). 对于100个数字,最后一个数字首次出现成功的机会为1%,并且每次失败时,您都要再两次调用getnum50()。

Sorry, this doesn't answer HOW to improve your efficiency, but it does explain why the efficiency concerns. 抱歉,这不能解决如何提高效率的问题,但确实可以解释效率问题的原因。 Hope it helps. 希望能帮助到你。

Your problem us that if you are toward the end of the list you will have to generate lots of random numbers to get a number in the couple of spots left. 您的问题是,如果您要到达列表的末尾,则必须生成大量随机数才能获得剩下的几个数字。 You could reduce a couple of ways one the fits into your current answer fairly will is as follows: 您可以通过以下几种方式减少适合您当前答案的方法:

  while(n[rnd-1] == 1)
  {
    rnd++;
    rnd=end%101;
  }
  n[rnd-1]=1;//to indicate which random number is generated
  number[n1]=rnd;
  System.out.println(number[n1]+" ");

However if you assume that the getnum50 is more expensive than anything you can write you could reduce the number of getnum50 that you call while filling in the second half of the list. 但是,如果您认为getnum50的成本比您可以编写的任何东西都要贵,则可以在填充列表的后半部分时减少调用的getnum50的数量。 Each time you find a number you could reduce your search space by one so (using non primitives): 每次找到一个数字,您都可以将搜索空间减少一个(使用非原语):

while(myArrayList.size()>1)
{
   int rnd=0;
   if(myArrayList.size()>50);
     rnd=((getnum50()-1)/50)+((getnum50()*2)%myArrayList.size())+1;
   else
     rnd=getnum50()%myArrayList.size()+1;
   System.out.println(rnd);
   myArrayList.remove(rnd);
}
System.out.println(myArrayList.get(rnd);
myArrayList.remove(rnd);

In this example your best, average and worst are 149 getnum50 calls; 在此示例中,您的最佳,平均和最差情况是149次getnum50调用;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM