How to generate non repeating random number

前端 未结 4 946
甜味超标
甜味超标 2021-01-07 04:45

I am trying to randomize numbers in an array. I am able to do that using arc4random() % [indexes count]

My problem is - If an array consists of 20 item

相关标签:
4条回答
  • 2021-01-07 05:16

    As per your requirement....kindly check this code

    Make this a property

    @synthesize alreadyGeneratedNumbers;
    

    Add these methods in your .m

    -(int)generateRandomNumber{
    
        int TOTAL_NUMBER=20;
    
        int low_bound = 0;
        int high_bound = TOTAL_NUMBER;
        int width = high_bound - low_bound;
        int randomNumber = low_bound + arc4random() % width;
    
        return randomNumber;
    }
    
    
    -(IBAction)randomNumbers:(UIButton *)sender
    {
    
        NSMutableArray *shuffle = [[NSMutableArray alloc] initWithCapacity:5];
    
        BOOL contains=YES;
        while ([shuffle count]<5) {
            NSNumber *generatedNumber=[NSNumber numberWithInt:[self generateRandomNumber]];
            //NSLog(@"->%@",generatedNumber);
    
            if (![alreadyGeneratedNumbers containsObject:generatedNumber]) {
                [shuffle addObject:generatedNumber];
                contains=NO;
                [alreadyGeneratedNumbers addObject:generatedNumber];
            }
        }
    
        NSLog(@"shuffle %@",shuffle);
        NSLog(@"Next Batch");
    
    
        if ([alreadyGeneratedNumbers count] >= TOTAL_NUMBER) {
            NSLog(@"\nGame over, Want to play once again?");//or similar kind of thing.
            [alreadyGeneratedNumbers removeAllObjects];
        }
    
    
    }
    

    Still I feel you need to some changes like

    it will give you correct value, but what if user pressed 5th time?

    out of 20 numbers you already picked 4 sets of 5 number, on on 6th time it will be in loop to search for next set of numbers and will become infinite.

    So what you can do is, keep the track of shuffle and once it reaches the limit i.e, 20/5=4 disable the random button.

    0 讨论(0)
  • 2021-01-07 05:27

    Declare array that contains already generated number in extension or header file

    @property (strong, nonatomic)NSMutableArray *existingNums;
    @property (assign, nonatomic)NSInteger maxLimit;
    @property (assign, nonatomic)NSInteger minLimit;
    

    Then implement given code in implementation file

    @synthesize existingNums;
    @synthesize maxLimit;
    @synthesize minLimit;
    
    - (NSInteger)randomNumber {
    
        if(!existingNums)
            existingNums = [NSMutableArray array];
    
        while (YES) {
    
            NSNumber *randonNum = [NSNumber numberWithInteger:minLimit+arc4random()%maxLimit];
    
            if([existingNums containsObject:randonNum]) {
    
                if([existingNums count] == (maxLimit - minLimit))
                    return -1; // All possible numbers generated in the given range
    
                continue;
            }
    
            [existingNums addObject:randonNum];
    
            return [randonNum integerValue];
        }
    
        return -1;   // return error
    }
    

    Hope this will help you :)

    0 讨论(0)
  • 2021-01-07 05:30

    The problem with all these answers is that you need to review your previous generated random numbers and that takes extra time if you need a large number of random integers.

    Another solution is using cryptography:

    1. Generate a random key
    2. Iterate between 0..n
    3. Encrypt each integer and apply modulo the number of alternatives do you want to use to the output of the function.

    There are some extra details to take into account that don't matter for your case.

    0 讨论(0)
  • 2021-01-07 05:32

    This one works for me:

        NSMutableArray *numbers = [NSMutableArray new];
        BOOL addElement = YES;
        int limit = 100; // Range from 0 to 36
        int numElem = 10; // Number of elements
        do
        {
            int ranNum = (arc4random() % limit) +1;
            if ([numbers count] < numElem) {
                for (NSNumber *oneNumber in numbers) {
                    addElement =([oneNumber intValue] != ranNum) ? YES:NO;
                    if (!addElement) break;
                }
                if (addElement) [numbers addObject:[NSNumber numberWithInt:ranNum]];
            } else {
                break;
            }
        } while (1);
        NSLog(@"%@",numbers);
    
    0 讨论(0)
提交回复
热议问题