zoukankan      html  css  js  c++  java
  • 算法-随机不重复数列生成

    今天上班的时候网上看到题目很简单,题目是这样的:给定一个正整数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();
            }
     
     
        }
    }
      
  • 相关阅读:
    C语言的选择结构和条件判断
    学习C语言必须知道的理论知识(第三章数据类型的分类)
    基本输入输出函数以及其格式.
    学习C语言必须知道的理论知识(第三章常量和变量)
    简单的算术题。
    学习C语言必须知道的理论知识(第二章算法)
    学习C语言必须知道的理论知识(第一章)
    学习C语言必须知道的理论知识(第三章常量类型,运算符和表达式)
    C语言中的循环控制语句.
    彻底弄懂JS中的this
  • 原文地址:https://www.cnblogs.com/xiaofeixiang/p/4234223.html
Copyright © 2011-2022 走看看