mko*_*yak 1 java string random
我有一些内容未知的随机字符串,众所周知的是内容是字母数字和小写.
我正在寻找一种简单的方法来大写该字符串中随机数字的字符.随机性越高越好.
我可以想到几种方法来做到这一点,但它们似乎都不是最优的.
好的第一个解决方案:
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();
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个解决方案,因为:
解决方案取决于您选择的概率模型.例如,如果你决定二项分布,那么你可以遍历字符,并以固定的概率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();
}
Run Code Online (Sandbox Code Playgroud)
另一方面,如果您想要确定给定字符串的超精确字母的确切数量,则问题变成随机样本问题(即选择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();
}
Run Code Online (Sandbox Code Playgroud)
此代码根据需要"动态"执行随机样本,仅考虑alpha字符.使用p = 0.5来切换正好一半的字母.