NSString 中的大写随机字符 [英] Uppercase random characters in a NSString

查看:48
本文介绍了NSString 中的大写随机字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出解决问题的最佳方法.我有一个随机生成的字母数字字符串:

I'm trying to figure out the best approach to a problem. I have an essentially random alphanumeric string that I'm generating on the fly:

NSString *string = @"e04325ca24cf20ac6bd6ebf73c376b20ac57192dad83b22602264e92dac076611b51142ae12d2d92022eb2c77f";

可以看到没有特殊字符,只有数字和字母,而且所有的字母都是小写.将此字符串中的所有字母更改为大写很容易:

You can see that there are no special characters, just numbers and letters, and all the letters are lowercase. Changing all the letters in this string to uppercase is easy:

[string capitalizedString];

困难的部分是我想大写这个字符串中的随机字符,而不是全部.例如,这可能是一次执行的输出:

The hard part is that I want to capitalize random characters in this string, not all of them. For example, this could be the output on one execution:

E04325cA24CF20ac6bD6eBF73C376b20Ac57192DAD83b22602264e92daC076611b51142AE12D2D92022Eb2C77F

这可能是另一个的输出,因为它是随机的:

This could be the output on another, since it's random:

e04325ca24cf20aC6bd6eBF73C376B20Ac57192DAd83b22602264E92dAC076611B51142AE12D2d92022EB2c77f

为了让这更容易,假设我还有两个变量:

In case it makes this easier, let's say I have two variables as well:

int charsToUppercase = 12;//hardcoded value for how many characters to uppercase here
int totalChars = 90;//total string length

在这种情况下,这意味着该字符串中的 90 个随机字符中有 12 个将被大写.到目前为止,我发现我可以相对轻松地遍历字符串中的每个字符:

In this instance it would mean that 12 random characters out of the 90 in this string would be uppercased. What I've figured out so far is that I can loop through each char in the string relatively easily:

NSUInteger len = [string length];
unichar buffer[len+1];

[string getCharacters:buffer range:NSMakeRange(0, len)];

NSLog(@"loop through each char");
for(int i = 0; i < len; i++) {
    NSLog(@"%C", buffer[i]);
}

仍然坚持在这个循环中选择随机字符为大写,所以不是所有的都是大写的.我猜 for 循环中的一个条件可以很好地解决这个问题,因为它足够随机.

Still stuck with selecting random chars in this loop to uppercase, so not all are uppercased. I'm guessing a condition in the for loop could do the trick well, given that it's random enough.

推荐答案

这里有一种方法,不是特别关心效率,但也不是愚蠢的效率:在原始字符串中创建一个数组字符,为哪些字符建立索引一路上都是字母...

Here's one way, not particularly concerned with efficiency, but not silly efficiency-wise either: create an array characters in the original string, building an index of which ones are letters along the way...

NSString *string = @"e04325ca24cf20ac6bd6ebf73c376b20ac57192dad83b22602264e92dac076611b51142ae12d2d92022eb2c77f";
NSMutableArray *chars = [@[] mutableCopy];
NSMutableArray *letterIndexes = [@[] mutableCopy];

for (int i=0; i<string.length; i++) {
    unichar ch = [string characterAtIndex:i];
    // add each char as a string to a chars collection
    [chars addObject:[NSString stringWithFormat:@"%c", ch]];
    // record the index of letters
    if ([[NSCharacterSet letterCharacterSet] characterIsMember:ch]) {
        [letterIndexes addObject:@(i)];
    }
}

现在,从 letterIndexes 中随机选择(在我们进行时删除它们)以确定哪些字母应为大写.将该索引处的 chars 数组成员转换为大写...

Now, select randomly from the letterIndexes (removing them as we go) to determine which letters shall be upper case. Convert the member of the chars array at that index to uppercase...

int charsToUppercase = 12;

for (int i=0; i<charsToUppercase && letterIndexes.count; i++) {
    NSInteger randomLetterIndex = arc4random_uniform((u_int32_t)(letterIndexes.count));
    NSInteger indexToUpdate = [letterIndexes[randomLetterIndex] intValue];
    [letterIndexes removeObjectAtIndex:randomLetterIndex];

    [chars replaceObjectAtIndex:indexToUpdate withObject:[chars[indexToUpdate] uppercaseString]];
}

注意 && 检查 letterIndexes.count.这可以防止 charsToUppercase 超过 chars 的数量的情况.转换为大写的上限是原始字符串中的所有字母.

Notice the && check on letterIndexes.count. This guards against the condition where charsToUppercase exceeds the number of chars. The upper bound of conversions to uppercase is all of the letters in the original string.

现在剩下的就是将 chars 数组连接成一个字符串...

Now all that's left is to join the chars array into a string...

NSString *result = [chars componentsJoinedByString:@""];
NSLog(@"%@", result);

EDIT 查看 OP 评论中的讨论,您可以将大写更改的概率作为输入而不是 charsToUppercase 输入参数.这会将这个想法压缩到一个循环中,数据转换更少......

EDIT Looking discussion in OP comments, you could, instead of acharsToUppercase input parameter, be given a probability of uppercase change as an input. That would compress this idea into a single loop with a little less data transformation...

NSString *string = @"e04325ca24cf20ac6bd6ebf73c376b20ac57192dad83b22602264e92dac076611b51142ae12d2d92022eb2c77f";

float upperCaseProbability = 0.5;
NSMutableString *result = [@"" mutableCopy];

for (int i=0; i<string.length; i++) {
    NSString *chString = [string substringWithRange:NSMakeRange(i, 1)];
    BOOL toUppercase = arc4random_uniform(1000) / 1000.0 < upperCaseProbability;

    if (toUppercase) {
        chString = [chString uppercaseString];
    }
    [result appendString:chString];
}
NSLog(@"%@", result);

然而,这假设任何字符的给定大写概率,而不是任何字母,因此它不会导致预定数量的字母改变大小写.

However this assumes a given uppercase probability for any character, not any letter, so it won't result in a predetermined number of letters changing case.

这篇关于NSString 中的大写随机字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆