Objective C 中的确定性随机播放
Deterministic shuffle in Objective C
Java中的这段代码是 Knuth 随机播放的实现,但是是确定性的,由随机数生成器的种子控制。
public String shuffleString(String data, long shuffleSeed) {
if(shuffleSeed!=0) {
Random rnd = new Random(shuffleSeed);
StringBuilder sb = new StringBuilder(data);
int n = data.length();
while(n>1) {
int k = rnd.nextInt(n--);
char t = sb.charAt(n);
sb.setCharAt(n, sb.charAt(k));
sb.setCharAt(k, t);
}
return sb.toString();
}
else {
return data;
}
}
如何在 Objective C 中实现确定性随机播放,在给定相同种子的情况下输出相同的随机播放顺序?我正在使用 srandom(_shuffleSeed);和 random()%(n--) 知道 arc4_random 更好,但不能播种。
- (NSString*) shuffleString:(NSString*) data withShuffleSeed:(int) shuffleSeed {
if(shuffleSeed!=0) {
srandom(_shuffleSeed);
NSMutableString *result = [[NSMutableString alloc] initWithString:data];
unsigned long n = data.length;
while(n>1) {
unsigned long k = random()%(n--);
unichar t = [result characterAtIndex:n];
NSRange r1 = {n,1};
[result replaceCharactersInRange:r1 withString:[NSString stringWithFormat:@"%c", [result characterAtIndex:k]]];
NSRange r2 = {k,1};
[result replaceCharactersInRange:r2 withString:[NSString stringWithFormat:@"%c", t]];
}
return result;
}
else {
return data;
}
}
目前,对于相同的输入参数,两种随机播放方法不会产生相同的结果。我确定我错过了什么!
有许多使用种子的伪随机数生成算法。您不能假设 Java 标准库中的算法与 Objective C.
中的 srandom
/random
使用完全相同的算法
Java 随机生成器使用:
The class uses a 48-bit seed, which is modified using a linear
congruential formula. (See Donald Knuth, The Art of Computer
Programming, Volume 3, Section 3.2.1.)
虽然出于向后兼容性的原因从未更改过,但它不再提供任何保证。
您的选择是:
- 取 Java source 并将其转换为 Objective-C(或者希望其他人之前已经这样做过)。请注意,Java 源是根据 GPL 或限制性 Oracle 许可获得许可的。如果您采用 GPL 许可下的版本,这会对您可以用于自己的代码的许可产生影响。
- 在 Objective-C 中搜索随机生成器的来源并将其转换为 Java。 (其中也可能有许可证限制,并且可能无法获得来源)。或者算法可能更恰当地指定,因此您可以仅从文档中在 Java 中实现它。
- 找到另一个具有 Java 和 Object-C 实现并给出相同结果(或编写一个)的随机生成器
Java中的这段代码是 Knuth 随机播放的实现,但是是确定性的,由随机数生成器的种子控制。
public String shuffleString(String data, long shuffleSeed) {
if(shuffleSeed!=0) {
Random rnd = new Random(shuffleSeed);
StringBuilder sb = new StringBuilder(data);
int n = data.length();
while(n>1) {
int k = rnd.nextInt(n--);
char t = sb.charAt(n);
sb.setCharAt(n, sb.charAt(k));
sb.setCharAt(k, t);
}
return sb.toString();
}
else {
return data;
}
}
如何在 Objective C 中实现确定性随机播放,在给定相同种子的情况下输出相同的随机播放顺序?我正在使用 srandom(_shuffleSeed);和 random()%(n--) 知道 arc4_random 更好,但不能播种。
- (NSString*) shuffleString:(NSString*) data withShuffleSeed:(int) shuffleSeed {
if(shuffleSeed!=0) {
srandom(_shuffleSeed);
NSMutableString *result = [[NSMutableString alloc] initWithString:data];
unsigned long n = data.length;
while(n>1) {
unsigned long k = random()%(n--);
unichar t = [result characterAtIndex:n];
NSRange r1 = {n,1};
[result replaceCharactersInRange:r1 withString:[NSString stringWithFormat:@"%c", [result characterAtIndex:k]]];
NSRange r2 = {k,1};
[result replaceCharactersInRange:r2 withString:[NSString stringWithFormat:@"%c", t]];
}
return result;
}
else {
return data;
}
}
目前,对于相同的输入参数,两种随机播放方法不会产生相同的结果。我确定我错过了什么!
有许多使用种子的伪随机数生成算法。您不能假设 Java 标准库中的算法与 Objective C.
中的srandom
/random
使用完全相同的算法
Java 随机生成器使用:
The class uses a 48-bit seed, which is modified using a linear congruential formula. (See Donald Knuth, The Art of Computer Programming, Volume 3, Section 3.2.1.)
虽然出于向后兼容性的原因从未更改过,但它不再提供任何保证。
您的选择是:
- 取 Java source 并将其转换为 Objective-C(或者希望其他人之前已经这样做过)。请注意,Java 源是根据 GPL 或限制性 Oracle 许可获得许可的。如果您采用 GPL 许可下的版本,这会对您可以用于自己的代码的许可产生影响。
- 在 Objective-C 中搜索随机生成器的来源并将其转换为 Java。 (其中也可能有许可证限制,并且可能无法获得来源)。或者算法可能更恰当地指定,因此您可以仅从文档中在 Java 中实现它。
- 找到另一个具有 Java 和 Object-C 实现并给出相同结果(或编写一个)的随机生成器