今天上班的時候網上看到題目很簡單,題目是這樣的:給定一個正整數n,需要輸出一個長度為n的數組,數組元素是隨機數,范圍為0 – n-1,且元素不能重復。比如 n = 3 時,需要獲取一個長度為3的數組,元素范圍為0-2;簡單的理解就是生成一個無序的隨機數組,在路上想了一下回來用三種方式方式實現了一下;OC實現了一下,文章最末尾順便有C#的是實現方法;
永遠的While
while基本上學過語言的最開始的流程分支語句都會涉及到while,如果存在就一直隨機,不存在就跳出判斷,一般最開始想到都是這樣方法:
+ (NSArray *)getResultOne:(NSInteger)count{ NSMutableArray *arr=[NSMutableArray array]; for (NSInteger i=0; i<count; i++) { NSInteger number=arc4random()%count; //如果存在就一直隨機下去 while ([arr containsObject:@(number)]) { number=arc4random()%count; } [arr addObject:@(number)]; } return arr; }
調用方式:
NSArray *arr=nil; arr=[ArrayRandom getResultOne:5]; for (NSInteger i=0; i<[arr count]; i++) { NSLog(@"%@",[arr[i]stringValue]); }
數組篩選
第二種方式其實說起來寫代碼葉遇到過這種情況,有點類似於從箱子中取球,放回去和不回去的這種模式,如果箱子中的每個球顏色都不一樣就是取出來就不放回去,那么取的下一個一定和之前的顏色不一樣,具體實現:
+ (NSArray *)getResultTwo:(NSInteger)count{ NSMutableArray *originalArr=[NSMutableArray array]; NSMutableArray *resultArr=[NSMutableArray array]; //按照順序生成一個數組 for (NSInteger i=0; i<count; i++) { [originalArr addObject:@(i)]; } NSInteger total=count; for (NSInteger i=0; i<count; i++) { NSInteger index=arc4random()%total; //隨機出來的結果添加到結果集 [resultArr addObject:originalArr[index]]; //刪除原始數組中的結果 [originalArr removeObject:originalArr[index]]; total--; } return resultArr; }
交換法
交換法的意思就是需要先初始化一個數組,隨機生成索引,每次隨機出來索引位置的值都放在頭部或者尾部,然后下次取索引的時候就不去頭部和尾部的索引,舉一個簡單的例子,假設初始化的數組是3,8,6,9,隨機出來的索引范圍是0-3,假設第一隨機隨機的時2,頭部交換就是將3和6換一個位置,6,8,3,9,下一次取的索引范圍是1-3,尾部交換也是類似,C#版本中是頭部交換,OC是尾部交換,原理是一樣的:
+(NSArray *)getResultThird:(NSInteger)count{ NSMutableArray *originalArr=[NSMutableArray array]; NSMutableArray *resultArr=[NSMutableArray array]; //按照順序生成一個數組 for (NSInteger i=0; i<count; i++) { [originalArr addObject:@(i)]; } NSInteger maxIndex=count-1; for (NSInteger i=0; i<count; i++) { NSInteger index=arc4random()%(maxIndex+1); [resultArr addObject:originalArr[index]]; //將隨機生成的數字賦值給最末位 originalArr[index]=originalArr[maxIndex]; //控制最大索引的值 maxIndex--; } return resultArr; }
這時我第一次寫的時候用的代碼,細心的可能發現定義了兩個數組,其實沒有必要,一個就夠,下面的是改進代碼:
+(NSArray *)getResultFour:(NSInteger)count{ NSMutableArray *resultArr=[NSMutableArray array]; //按照順序生成一個數組 for (NSInteger i=0; i<count; i++) { [resultArr addObject:@(i)]; } NSInteger maxIndex=count-1; for (NSInteger i=0; i<count; i++) { NSInteger index=arc4random()%(maxIndex+1); //隨機的值和末位進行互換 NSString *temp=resultArr[index]; resultArr[index]=resultArr[maxIndex]; resultArr[maxIndex]=temp; //控制最大索引的值 maxIndex--; } return resultArr; }
調用方式同之前的一樣:
NSArray *arr=nil; arr=[ArrayRandom getResultThird:5]; for (NSInteger i=0; i<[arr count]; i++) { NSLog(@"%@",[arr[i]stringValue]); } NSArray *arr=nil; arr=[ArrayRandom getResultFour:5]; for (NSInteger i=0; i<[arr count]; i++) { NSLog(@"%@",[arr[i]stringValue]); }
C#版本代碼
class Program { static void Main(string[] args) { //初始化一個數組,如果數組沒有賦值,默認是0 //int[] arr = SolveProblemWayOne(5); //int[] arr = SolveProblemWaySecond(5); //int[] arr = SolveProblemWayThird(10); int[] arr = SolveProblemWayFour(5); for (int i = 0; i < arr.Length; i++) { Console.Write(arr[i].ToString()); } Console.ReadKey(); } /// <summary> /// 循環判斷隨機出來的數字是否在數組中 /// </summary> /// <param name="total"></param> /// <returns></returns> public static int[] SolveProblemWayOne(int count) { List<int> resultList = new List<int>(); Random random = new Random(); for (int i = 0; i < count; i++) { int number = random.Next(1, count + 1); while (resultList.Contains(number)) { number = random.Next(1, count + 1); } resultList.Add(number); } return resultList.ToArray(); } /// <summary> /// 按照順序生成一個數組 /// </summary> /// <param name="total"></param> /// <returns></returns> public static int[] SolveProblemWaySecond(int count) { List<int> orignalList = new List<int>(); List<int> resultList = new List<int>(); for (int i = 0; i < count; i++) { orignalList.Add(i); } int maxIndex = count; Random random = new Random(); for (int i = 0; i < count; i++) { //隨機索引 int index = random.Next(0, maxIndex); resultList.Add(orignalList[index]); orignalList.RemoveAt(index); maxIndex--; } return resultList.ToArray(); } /// <summary> /// 不刪除數據,然后的問題就是給最后的東西賦值 /// </summary> /// <param name="count"></param> /// <returns></returns> public static int[] SolveProblemWayThird(int count) { List<int> orignalList = new List<int>(); List<int> resultList = new List<int>(); for (int i = 0; i < count; i++) { orignalList.Add(i); } int minIndex =0; Random random = new Random(); for (int i = 0; i < count; i++) { //隨機索引 int index = random.Next(minIndex, count); resultList.Add(orignalList[index]); //交換,由於索引自減,不需要將隨機的值賦值到最后 //int temp = orignalList[index]; orignalList[index] = orignalList[minIndex]; //orignalList[minIndex] = temp; minIndex++; } return resultList.ToArray(); } /// <summary> /// 簡潔方式 /// </summary> /// <param name="count"></param> /// <returns></returns> public static int[] SolveProblemWayFour(int count) { List<int> resultList = new List<int>(); for (int i = 0; i < count; i++) { resultList.Add(i); } int minIndex=0; Random random = new Random(); for (int i = 0; i < count; i++) { //隨機索引 int index = random.Next(minIndex, count); //頭部交換 int temp = resultList[index]; resultList[index]=resultList[minIndex]; resultList[minIndex] = temp; minIndex++; } return resultList.ToArray(); } } }