隨筆 - 154  文章 - 60  trackbacks - 0
          <2008年2月>
          272829303112
          3456789
          10111213141516
          17181920212223
          2425262728291
          2345678

          聲明:

          該blog是為了收集資料,認識朋友,學習、提高技術,所以本blog的內容除非聲明,否則一律為轉載??!

          感謝那些公開自己技術成果的高人們?。?!

          支持開源,尊重他人的勞動??!

          常用鏈接

          留言簿(3)

          隨筆分類(148)

          隨筆檔案(143)

          收藏夾(2)

          其他

          學習(技術)

          觀察思考(非技術)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          /**
           *
           *問題或許可以是這樣:產生m個隨機正整數,要求范圍是從1到n,平且它們互不相同。
          問題或許可以這樣解決:

          假設我們已經有了經過排序的(升序),且滿足要求的k個正整數,我們繼續:
          1、在從1到n-k的區間范圍內,產生一個隨機的正整數i1;
          2、統計在已有序列中比i1小的數,將其個數加到i1上,得到i2;再統計從i1到i2數的個數,得到i3;一直循環,直到i不變為止。然后,把i插入已有的序列。這個過程相當于從頭數出i1個空白,以此來保證新的數是隨機的。
          3、這時得到了k+1個滿足要求的數,然后就循環吧。
          上面的方法適用于n很大,但是m很小的時候。

          如果m和n都很大,并且希望一次性的產生,那么:
          1先產生有一定冗余的隨機正整數,然后排序,然后去掉相同的數。
          如果,產生了超額的數,可以將數列再打亂順序,然后,取出符合規定的數目的數。

          當然,也可以兩種方法相結合,就是:
          1、先產生超過需求的、有一定冗余的隨機正整數,然后排序,然后去掉相同的數,并且保存下來。記錄它的數目m1 >m;
          2、當要用時,在產生一個從1到m的隨機數j,然后取出數據庫中第j個數,輸出,并且把它從數據庫中刪除到。
           *
           *
           *
           *
           *
           *
           *
           *
           *數據有點大,用了128m
          start_1   ();   是即時輸出(因為用boolean數組,所以內存小得多)
          start_2   ();   是把數據存進數組,以便再處理(需要內存很大,不贊成使用)
          如果要處理數據,可以用   start_1   ();   把數據保存進文件,再從文件中讀取數據進行處理。

           */
          public class Main{
           
           public final int n = 10000000;
           
           public Main () {
                  start_1();
                  //start_2 ();
              }
             
              public static void main (String[] args) {
                  new Main();
              }
             
              public void start_1() {
                  //布朗型默認為 false
                  boolean[] barr = new boolean[n];
                  //
                  java.util.Random r = new java.util.Random ();
                  int j = 0, x;
                  int m = n;
                  while(j < m) {
                      x = r.nextInt (n);
                      if (! barr[x]) {
                          j++;
                          barr[x] = true;
                          System.out.println (x);
                      }
                  }
              }
             
              public void start_2() {
                  //整型默認為 0
                  int[] iarr = new int[n];
                  //
                  java.util.Random r = new java.util.Random ();
                  int j = 0, x;
                  int m = n;
                  //少循環一次,因為要生成 0
                  while(j < m-1) {
                      x = r.nextInt (n);
                      if (iarr[x] == 0) {
                          j++;
                          iarr[x] = j;
                      }
                  }
              }
          }
          /*
           *上面的算法,沒有優化,生成數據耗時間。
          下面的算法改進了一下。生成所有數據半分鐘左右。
          +----------
          |   0...999999
          |   .
          |   .
          |   .
          |   99

          Java code
          public class Main {
             
              public Main () {
                  start_1 ();
                  start_2 ();
              }
             
              public static void main (String[] args) {
                  new Main ();
              }
             
              ** void start_1 () {
                  for (int i = 0; i < n; i++) {
                      byte j = 0;
                      while(j < m-1) {
                          int x = r.nextInt (m);
                          if (barr_1[x] == 0) {
                              j++;
                              barr_1[x] = j;
                          }
                      }
                  }
              }
             
              ** void start_2 () {
                  int j = 0;
                  while(j < n) {
                      int x = r.nextInt (n);
                      int y = (int) barr_2[x];
                      if (y < m) {
                          j++;
                          barr_2[x]++;
                          int z = ((int) barr_1[x][y]) * n;
                          //System.out.println (x + z);
                      }
                  }
              }
             
              ** final int s = 10000*10000;
              ** final int m = 100;
              ** final int n = s/m;
              ** byte[][] barr_1 = new byte[n][m];
              ** byte[] barr_2 = new byte[n];
              ** java.util.Random r = new java.util.Random ();
             
          }
          */

          /*
           *和一位仁兄在另一個帖子爭論中,受到啟發。
          終于悟出一種時間復雜度極低的算法。
          (可以證明,任意一個數   在   任意位置的概率   都為   1/n)

          因為內存不夠,所以改成了7個9來算??倳r間2秒

          Java code
          public class Main {
             
              public Main () {
                  start ();
              }
             
              public static void main (String args[]) {
                  new Main ();
              }
             
              ** void start () {
                  java.util.Random r = new java.util.Random ();
                  for (int i = 0; i < n; i++) {
                      int x = r.nextInt (i+1);
                      iarr = iarr[x];
                      iarr[x] = i;
                  }
                  //
                  int m = 10;
                  for (int i = 0; i < m; i++) {
                      System.out.print (iarr + " ");
                  }
              }
             
              ** final int n = 1000*10000;
              ** int[] iarr = new int[n];
             
          }
          */

          posted on 2008-02-01 11:20 lk 閱讀(785) 評論(0)  編輯  收藏 所屬分類: j2se
          主站蜘蛛池模板: 嫩江县| 苗栗县| 来安县| 万安县| 文安县| 通化县| 克山县| 怀来县| 肇东市| 黄大仙区| 司法| 稻城县| 高唐县| 且末县| 获嘉县| 芮城县| 景洪市| 宿迁市| 湘潭市| 定州市| 清流县| 崇州市| 同仁县| 孝义市| 靖江市| 鹿邑县| 天柱县| 尖扎县| 台北县| 河间市| 临城县| 高邑县| 延吉市| 凤城市| 辽中县| 桓仁| 修文县| 阳山县| 唐河县| 柳林县| 攀枝花市|