我有一些内容未知的随机字符串,已知的是内容是字母数字和小写。
我正在寻找一种简单的方法来大写该字符串中的随机字母字符数。随机性越高越好。
我能想到几种方法来做到这一点,但似乎没有一种是最佳的。
好的第一个解决方案:
public String randomizeCase(String myString){
Random rand = new Random();
StringBuilder build = new StringBuilder();
for(char c: myString.toCharArray()){
String s = new String(c);
if(Character.isLetter(c) && rand.nextBoolean()){
s = s.toUpperCase();
}
build.append(s);
}
return build.toString();
}
我不喜欢这个解决方案,因为:
- 50% 的概率每个字符都是大写的不等于 50% 的概率 50% 的字符是大写的
- 有可能什么都不大写
- 字符到字符串的转换很丑
最佳答案
解决方案取决于您选择的概率模型。例如,如果您决定 binomial distribution ,然后你可以遍历字符,并以固定概率 p 将每个字符切换为大写。大写字母的预期数量将是 p * str.length():
public static String randomUpper(String str, double p) {
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isLetter(c) && Math.random() < p)
c = Character.toUpperCase(c);
sb.append(c);
}
return sb.toString();
}
另一方面,如果您想确定给定字符串的大写字母的确切数量,那么问题就变成了 random sample problem (即选择 M 个位置以切换出字符串中的 N 个位置)。这可能比第一种方法快得多,当 M 远小于 N 时(尽管对于 Java 的不可变字符串,差异变得很小,因为无论如何您都必须复制整个字符串)。
-- 编辑--
现在您已经明确了要求,请考虑以下事项:
public static String randomUpper2(String str, double p) {
int letters = 0;
for (int i = 0; i < str.length(); i++) {
if (Character.isLetter(str.charAt(i)))
letters++;
}
int toChoose = (int) (p * letters);
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isLetter(c)) {
if (Math.random() < (toChoose/(double)letters)) {
c = Character.toUpperCase(c);
toChoose--;
}
letters--;
}
sb.append(c);
}
return sb.toString();
}
此代码根据需要“即时”执行随机样本,仅考虑字母字符。使用 p=0.5 正好切换一半的字母。
关于java - 来自随机字母数字字符串的大写随机字符数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3292952/