Я сделал случайный выбор для А-Я. Случайная буква отображается на этикетке. все работает нормально. Но письмо не должно повторяться, пока не будет называться каждая буква от 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;
}}
-1
euleec7 24 Фев 2015 в 01:22

4 ответа

Лучший ответ

Есть много разных способов сделать это. Я предлагаю использовать изменяемый массив:

Добавьте этот оператор в свой .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 (), и не страдает от " modulo bias " (ссылка), как в выражении rand()%range.

Обратите внимание, что описанный выше метод может дать вам последнюю случайную букву (например, «а»), а затем при следующем вызове повторно заполнить массив и дать вам еще одну букву «а» из вновь заполненного массива. Однако вероятность того, что это произойдет, составляет всего 1 к 26.

Вы можете настроить приведенный выше код, чтобы он запомнил последний передаваемый вам символ и не выдавал вам этот же символ дважды подряд, если это важно.

Вы можете довольно легко немного изменить его, чтобы он выдавал вам буквы по одной, пока он не станет пустым, а затем вернул бы nil, а затем написать отдельный метод для его заполнения. Таким образом вы сможете получить ровно 26 неповторяющихся символов и знать, когда вы собираетесь повторить еще один набор из 26 символов.

0
Community 23 Май 2017 в 10:24

Учитывая эти методы:

- (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
0
Murray Sagal 24 Фев 2015 в 11:52

Поскольку строка 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);
0
Mornirch 23 Фев 2015 в 23:12

Вместо переключателя, возможно, сохраните алфавит в 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;
}
1
Josh Gafni 24 Фев 2015 в 21:33