今天上班的時候網上看到題目很簡單,題目是這樣的:給定一個正整數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();
}
}
}
