Objective-C 随机字母不重复

Objective-C random alphabet no repeat

我做了一个随机的 A-Z。随机字母显示在标签中。一切正常。但是在调用 A-Z 中的每个字母之前,该字母不应重复。 我是 xcode 的新人,需要一点帮助。 这是我在 .m 文件中的代码。

NSString *letters = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-(NSString *) randomStringWithLength:(int) len {

NSMutableString *randomString = [NSMutableString stringWithCapacity: len];

for (int i=26; i<len; i++) {
    [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random() % [letters length]]]; buchstabeAusgabe.text = randomString;
}

return randomString;}



-(void)neuerGenerator {

int text = rand() %26;

switch (text) {
    case 0:
        buchstabeAusgabe.text =@"A";
        break;
    case 1:
        buchstabeAusgabe.text =@"B";
        break;
    case 2:
        buchstabeAusgabe.text =@"C";
        break;
    case 3:
        buchstabeAusgabe.text =@"D";
        break;
    case 4:
        buchstabeAusgabe.text =@"E";
        break;
    case 5:
        buchstabeAusgabe.text =@"F";
        break;
    case 6:
        buchstabeAusgabe.text =@"G";
        break;
    case 7:
        buchstabeAusgabe.text =@"H";
        break;
    case 8:
        buchstabeAusgabe.text =@"I";
        break;
    case 9:
        buchstabeAusgabe.text =@"J";
        break;
    case 10:
        buchstabeAusgabe.text =@"K";
        break;
    case 11:
        buchstabeAusgabe.text =@"L";
        break;
    case 12:
        buchstabeAusgabe.text =@"M";
        break;
    case 13:
        buchstabeAusgabe.text =@"N";
        break;
    case 14:
        buchstabeAusgabe.text =@"O";
        break;
    case 15:
        buchstabeAusgabe.text =@"P";
        break;
    case 16:
        buchstabeAusgabe.text =@"Q";
        break;
    case 17:
        buchstabeAusgabe.text =@"R";
        break;
    case 18:
        buchstabeAusgabe.text =@"S";
        break;
    case 19:
        buchstabeAusgabe.text =@"T";
        break;
    case 20:
        buchstabeAusgabe.text =@"U";
        break;
    case 21:
        buchstabeAusgabe.text =@"V";
        break;
    case 22:
        buchstabeAusgabe.text =@"W";
        break;
    case 23:
        buchstabeAusgabe.text =@"X";
        break;
    case 24:
        buchstabeAusgabe.text =@"Y";
        break;
    case 25:
        buchstabeAusgabe.text =@"Z";
        break;

    default:
        break;
}}

代替开关,也许将字母表存储在 NSMutableArray 中。取一个字母后,将其从数组中删除。而不是 %26%[array count]。要查找数组中的项目,请使用 [array objectAtIndex:index],其中索引是随机数。

我现在不在 XCode,但我会尝试写出完整的代码:

- (NSString *) randomStringWithLength:(int) len andAlphabet: (NSString *) alphabet {
    NSMutableArray *alphabetArrayMut = [[self arrayFromString: alphabet] mutableCopy];
    NSMutableString *resultString = [NSMutableString stringWithString:@""];
    while([alphabetArrayMut count]&&[resultString length]<len){
        int index = rand() % [alphabetArrayMut count];
        NSString *charToAdd = [alphabetArrayMut objectAtIndex:index];
        [resultString appendString:charToAdd];
        [alphabetArrayMut removeObjectAtIndex:index];
    }
    return [resultString copy];
}

- (NSArray *) arrayFromString: (NSString *) string{
    NSMutableArray *characters = [[NSMutableArray alloc] initWithCapacity:[string length]];
    for (int i=0; i < [string length]; i++) {
        NSString *ichar  = [NSString stringWithFormat:@"%c", [string characterAtIndex:i]];
        [characters addObject:ichar];
    }
    return [characters copy];
}

请注意,使用递归可能更容易。不幸的是,我现在不在我的 mac 上,所以我无法测试它:

- (NSString *) randomStringWithLength:(int) len andAlphabet: (NSString *) alphabet {
    if(len <= 0 || ![alphabet count]){ // base case
         return @"";
    }
    int index = rand() % [alphabet count];
    NSString *chosenLetter = [alphabet substringWithRange:NSMakeRange(index, 1)];
    NSString *newAlphabet = [alphabet stringByReplacingCharactersInRange:NSMakeRange(index, 1) withString:@""];
    NSString *resultString = [NSString stringWithFormat:@"%@%@",chosenLetter,[self randomStringWithLength:len-1,newAlphabet];
    return resultString;
}

因为c字符串以'\0'结尾,我们需要27个字节。

    NSString *alp = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char cstr[27];

    [alp getCString:cstr maxLength:27 encoding:NSUTF8StringEncoding];

    // do i from 25 to 0. to 1 is ok, also
    for (int i = alp.length - 1; i >= 0; --i) {
        int mark = arc4random_uniform(i);
        char temp = cstr[i];
        cstr[i] = cstr[mark];
        cstr[mark] = temp;
    }

    NSString *str = [NSString stringWithUTF8String:cstr];

    NSLog(@"%@", str);

有很多不同的方法可以做到这一点。我的建议是使用可变数组:

将此语句添加到您的 .h 文件中:

NSMutableArray *randomLetters;

然后将此方法添加到您的 .m 文件中:

(已编辑代码以清除大量拼写错误和小错误)

- (NSString *) randomLetter;
{
  if (randomLetters == nil)
    randomLetters = [NSMutableArray arrayWithCapacity: 26];
  if (randomLetters.count == 0)
  {
    for (unichar aChar = 'A';  aChar <= 'Z'; aChar++)
    {
      [randomLetters addObject: [NSString stringWithCharacters: &aChar length: 1]];
    }
  }
  NSUInteger randomIndex = arc4random_uniform((u_int32_t)randomLetters.count);
  NSString *result =  randomLetters[randomIndex];
  [randomLetters removeObjectAtIndex: randomIndex];
  return result;
}

(免责声明:我在 SO 编辑器中输入了该代码。我没有尝试编译它,因此它可能包含一些小错别字。)

每次调用randomLetter方法都会给你一个单一的、不重复的随机字母,直到剩下的随机字母数组为空。届时它将用完整的字母表重新填充数组并重新开始。

随机数生成器 arc4random_uniform() 提供比 rand() 更好的结果,并且不会像表达式 rand()%range 确实如此。

请注意,上述方法可能会为您提供最后一个随机字母(例如 "a""),然后在下一次调用时重新填充数组,并为您提供另一个 [=34] =] 来自新填充的数组。但是,发生这种情况的几率仅为 26 分之一。

您可以调整上面的代码,让它记住它给您的最后一个字符,如果这很重要,则不会连续两次给您相同的字符。

你可以很容易地稍微改变它,这样它会一次给你一个字母,直到它是空的,然后 return nil,然后写一个单独的方法来填充它。这样你就可以获得恰好 26 个非重复字符,并知道你何时要用另一组 26 个字符重复。

鉴于这些方法:

- (NSString *)stringOfRandomLettersWithLength:(NSUInteger)length {

    if (length > 26) {
        return nil;
    }

    NSMutableString *stringOfRandomLetters = [NSMutableString stringWithCapacity:length];
    NSArray *letters = @[ @"A",  @"B",  @"C",  @"D",  @"E",  @"F",  @"G",  @"H",  @"I",  @"J",  @"K",  @"L",  @"M",  @"N",  @"O",  @"P",  @"Q",  @"R",  @"S",  @"T",  @"U",  @"V",  @"W",  @"X",  @"Y",  @"Z" ];
    NSMutableArray *unusedLetters = [letters mutableCopy];
    NSString *randomLetter;

    for (int i=0; i<length; i++) {
        randomLetter = [self randomItemFromArray:unusedLetters];
        [unusedLetters removeObject:randomLetter];
        [stringOfRandomLetters appendString:randomLetter];
    }

    return stringOfRandomLetters;
}

- (NSString *)randomItemFromArray:(NSArray *)items {

    if (items.count < 1) {
        return nil;
    }

    return items[ arc4random_uniform((u_int32_t)items.count) ];
}

您可以像这样创建一串随机的、不同的字母:

NSString *label = [self stringOfRandomLettersWithLength:26];
NSLog(@"label= %@", label);

在控制台中,您会看到如下内容:

label= YGRHCXTFDZLKNPAIEOJSUQWVMB