【问题标题】:Fill an array with random characters chosen from a list without duplicates用从列表中选择的随机字符填充数组,不重复
【发布时间】:2012-09-28 19:26:55
【问题描述】:

我正在尝试用 6 个不同字符中的 4 个填充一个数组,其中数组中的每个字符都不同。放入数组的字符基于 switch 语句。然后我想通过数组返回以确保我刚刚放置的字符不在数组中,如果是,我必须放入不同的字符。我该怎么做呢?我不想重新填充整个阵列,就这一点。

这是我目前的代码,包括 cmets:

-(void) fillarray{

for (int i=0; i<4; i++)
{
    int randomNum = arc4random() % 6; // generates a random number

          switch (randomNum) // based on the number generated, it choses what color will be placed into the slot
    {
        case 1:
            colorarray[i] ='r';
            break;

        case 2:
            colorarray[i] ='o';
            break;

        case 3:
            colorarray[i] ='y';
            break;

        case 4:
            colorarray[i] ='g';
            break;
        case 5:
            colorarray[i] = 'b';

        case 6:
            colorarray[i] = 'p';

        default:
            break;
    }

    for (int j=0; j<4; j++) // runs through the array to ensure that the recently placed color does not match previous placed colors
    {
        while (j /= i)

            if (colorarray[i]==colorarray[j]) // if the color is already in the array
                                            //try again to place another color in this location

    }

【问题讨论】:

  • 如果您想要真正简单的唯一性,请使用 NSSet。 NSSet 将删除其中包含的所有非唯一对象。
  • 无论如何,我不会担心问题的独特部分。我添加了一个解决方案,它只是打乱选择并从中选择前 n 个项目。

标签: objective-c arrays char switch-statement


【解决方案1】:

首先你得到一个你可以提取的所有可能字符的数组(你也可以使用 NSArray,在这里我想你想使用 C 样式的数组):

char characters[]={'r','o','y','g','b','p'};
int length=6;

然后,每次提取一个字符时,都会减小长度变量,并将最后一个提取的字符与最后一个交换,以确保它不会再次被使用:

int randomNum = arc4random() % length;
< put characters[randomNum] somewhere>
char temp=characters[randomNum];
characters[randomNum]=characters[length-1];
characters[length-1]=temp;
length--;    

PS:% 操作数返回商的余数,所以数字 %N 永远不会是 N,它的范围是从 0 到 N-1。

【讨论】:

    【解决方案2】:

    我会使用这个,基于Fisher-Yates shuffling algorithm

    NSArray * array = @[ @"r", @"o", @"y", @"g", @"b", @"p" ] ;
    array = [ [ array shuffledArray ] subarrayWithRange:(NSRange){ .length = 4 } ] ;
    

    -shuffledArray 通过以下方式添加到 NSArray 的位置:

    @implementation NSArray ( Shuffling )
    
    -(NSArray*)shuffledArray
    {
        NSMutableArray * result = [ NSMutableArray arrayWithCapacity:self.count ] ;
        [ result addObject:self[0] ] ;
        for( NSUInteger index=1, count = self.count; index < count; ++index )
        {
            int j = arc4random_uniform( (unsigned int)index ) ;
            [ result addObject:result[j] ] ;
            [ result replaceObjectAtIndex:j withObject:self[ index ] ] ;
        }
    
        return result ;
    }
    
    @end
    

    【讨论】:

      【解决方案3】:

      函数应该如下所示:

          int found = 1;
          for (int i=0; i<4; i++)
          {
              while(found) {
                 int randomNum = arc4random() % 6;
                 switch (randomNum) 
                 {
                    case 1:
                      colorarray[i] ='r';
                      break;
      
                    case 2:
                      colorarray[i] ='o';
                      break;
      
                   case 3:
                     colorarray[i] ='y';
                     break;
      
                   case 4:
                     colorarray[i] ='g';
                     break;
                   case 5:
                     colorarray[i] = 'b';
                     break;
      
                   case 6:
                     colorarray[i] = 'p';
      
                   default:
                     break;
                 }
                 found = 0;
                 for (int j = i-1; i >= 0; j--) {
                    if (colorarray[i] == colorarray[j])
                       found = 1;
                 }
              }
       }
      

      【讨论】:

        【解决方案4】:

        另外,如果您不想使用 switch 或(本质上)通过递减长度变量来删除从数组中收到的字符,您可以随时这样做:

        char colorarray[5] = {0,0,0,0,'\0'};
        char possibleCharacters[6] = {'r', 'o', 'y', 'g', 'b', 'p'};
        BOOL isNotUnique = NO;
        
        for(int i = 0; i < 4; i++){
            do{
                colorarray[i] = possibleCharacters[arc4random() % 6];
                for(int j = i - 1; j > -1; --j){
                    if(colorarray[i] == colorarray[j]){
                        isNotUnique = YES;
                        break;
                    }
                    else isNotUnique = NO;
                }
            }while(isNotUnique);
        }
        
        NSLog(@"%s", colorarray);
        

        获取字符的实际循环基本上是这样的:

        1    for each spot in the colors arrays
        2        generate a random number and use it to get a character
        3        check to see if the character is identical to any spot before this one
        4        if our new character matched any previous one, repeat from 2 on
        

        【讨论】:

          【解决方案5】:

          这是另一种随机排列数组的方法(获取随机排列的前 X 个元素)。基本上,你按照 Ramy Alzury 和 nielsbot 的反应去做。算法是这样的。

          Do this 10 times the length of the array
              swap the last element with a random element chosen from the array
          

          最后这应该会产生一个随机打乱的数组(你正在打乱它 10 次)

          这是 Objective C 中的一个示例函数。

          -(NSArray *) shuffleArray:(NSArray *) arr{
              NSMutableArray * mArr = [NSMutableArray arrayWithArray:arr];
              for(int i=0;i<arr.count*10;i++){
                  int num = arc4random()%arr.count;
                  NSString * temp = (NSString *)[mArr objectAtIndex:arr.count-1];
                  [mArr replaceObjectAtIndex: arr.count-1 withObject:[mArr objectAtIndex:num]]; 
                  [mArr replaceObjectAtIndex:num withObject:temp];
              }
              return [NSArray arrayWithArray:mArr];
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-06-08
            • 1970-01-01
            • 1970-01-01
            • 2023-01-11
            • 1970-01-01
            • 1970-01-01
            • 2011-11-13
            相关资源
            最近更新 更多