GVKun编程网logo

如何在Swift中生成大范围的随机数?(如何在swift中生成大范围的随机数数据)

8

本文的目的是介绍如何在Swift中生成大范围的随机数?的详细情况,特别关注如何在swift中生成大范围的随机数数据的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解如何

本文的目的是介绍如何在Swift中生成大范围的随机数?的详细情况,特别关注如何在swift中生成大范围的随机数数据的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解如何在Swift中生成大范围的随机数?的机会,同时也不会遗漏关于#随机数#生成指定范围的随机数、c – 无法为整数生成全范围的随机数、ios – 在Swift 3.0中生成随机字节、ios – 在Swift中生成一个随机单词的知识。

本文目录一览:

如何在Swift中生成大范围的随机数?(如何在swift中生成大范围的随机数数据)

如何在Swift中生成大范围的随机数?(如何在swift中生成大范围的随机数数据)

我正在寻找一种有效的方法来在Swift中生成具有任意范围(甚至可能是UInt.maxInt.max)的大数(包括浮点类型!)。

我见过的所有现有问题要么因大值(UInt.max)而崩溃,要么不支持范围。我知道您可以从中读取/dev/urandom随机字节,但这无助于将这些值限制为给定的时间间隔(而且我敢肯定,循环直到无效为止)。

答案1

小编典典

这是的可能解决方案UIntInt并且Double可以与所有这些类型一起使用。它被编写为扩展方法(现已针对Swift2进行了更新),但是对于全局函数也可以做到这一点。

请注意,仅arc4random_uniform()产生32位数字,因此如果Int/ UInt是64位整数(所有OS
X机器和所有较新的iOS设备都是这种情况),则不能使用该数字。

因为UInt我们使用的技术(这只是的快速翻译)。如果范围涵盖的整个范围,则将UInt单独处理。

extension UInt {    static func random(minValue minValue : UInt, maxValue : UInt) -> UInt {        precondition(minValue <= maxValue, "attempt to call random() with minValue > maxValue")        if minValue == UInt.min && maxValue == UInt.max {            // Random number in the full range of UInt:            var rnd : UInt = 0            arc4random_buf(&rnd, sizeofValue(rnd))            return rnd        } else {            // Compute random number in the range 0 ... (maxValue-minValue),            // using the technique from             // https://stackoverflow.com/a/26550169/1187415, https://stackoverflow.com/a/10989061/1187415            // and avoiding the "modulo bias problem":            let range = maxValue - minValue + 1            let randLimit = UInt.max - UInt.max % range            var rnd : UInt = 0            repeat {                arc4random_buf(&rnd, sizeofValue(rnd))            } while rnd >= randLimit            rnd = rnd % range            // Transform `rnd` back to the range minValue ... maxValue:            return minValue + rnd        }    }}

例子:

let u1 = UInt.random(minValue: 1000, maxValue: 2000)let u2 = UInt.random(minValue: UInt.min, maxValue: UInt.max)

使用溢出运算符和bitPattern:转换可以将有符号整数的情况减少为无符号情况:

extension Int {    static func random(minValue minValue : Int, maxValue : Int) -> Int {        precondition(minValue <= maxValue, "attempt to call random() with minValue > maxValue")        // Compute unsigned random number in the range 0 ... (maxValue-minValue):        let diff = UInt(bitPattern: maxValue &- minValue)        let rnd = UInt.random(minValue: 0, maxValue: diff)        // Transform `rnd` back to the range minValue ... maxValue:        return minValue &+ Int(bitPattern: rnd)    }}

例子:

let i1 = Int.random(minValue: -1000, maxValue: 1000)let i2 = Int.random(minValue: Int.min, maxValue: Int.max)

最后,一个简单的实现Double

extension Double {    static func random(minValue minValue : Double, maxValue : Double) -> Double {        precondition(minValue <= maxValue, "attempt to call random() with minValue > maxValue")        // Random floating point number in the range 0.0 ... 1.0:        let rnd = Double(UInt.random(minValue: 0, maxValue: UInt.max))/Double(UInt.max)        // Scale to range minValue ... maxValue:        return minValue + rnd * (maxValue - minValue)    }}

例:

let d = Double.random(minValue: 10.5, maxValue: 123.5)

Swift 3更新:

extension UInt {    static func random(minValue: UInt, maxValue: UInt) -> UInt {        precondition(minValue <= maxValue, "attempt to call random() with minValue > maxValue")        if minValue == UInt.min && maxValue == UInt.max {            // Random number in the full range of UInt:            var rnd: UInt = 0            arc4random_buf(&rnd, MemoryLayout.size(ofValue: rnd))            return rnd        } else {            // Compute random number in the range 0 ... (maxValue-minValue),            // using the technique from             // https://stackoverflow.com/a/26550169/1187415, https://stackoverflow.com/a/10989061/1187415            // and avoiding the "modulo bias problem":            let range = maxValue - minValue + 1            let randLimit = UInt.max - UInt.max % range            var rnd: UInt = 0            repeat {                arc4random_buf(&rnd, MemoryLayout.size(ofValue: rnd))            } while rnd >= randLimit            rnd = rnd % range            // Transform `rnd` back to the range minValue ... maxValue:            return minValue + rnd        }    }}extension Int {    static func random(minValue: Int, maxValue: Int) -> Int {        precondition(minValue <= maxValue, "attempt to call random() with minValue > maxValue")        // Compute unsigned random number in the range 0 ... (maxValue-minValue):        let diff = UInt(bitPattern: maxValue &- minValue)        let rnd = UInt.random(minValue: 0, maxValue: diff)        // Transform `rnd` back to the range minValue ... maxValue:        return minValue &+ Int(bitPattern: rnd)    }}extension Double {    static func random(minValue: Double, maxValue: Double) -> Double {        precondition(minValue <= maxValue, "attempt to call random() with minValue > maxValue")        // Random floating point number in the range 0.0 ... 1.0:        let rnd = Double(UInt.random(minValue: 0, maxValue: UInt.max))/Double(UInt.max)        // Scale to range minValue ... maxValue:        return minValue + rnd * (maxValue - minValue)    }}

#随机数#生成指定范围的随机数

#随机数#生成指定范围的随机数

illustration

捡起丢下一个多月的Java,重新复习书本上的东西,来到随机数这一部分:
问题:生成指定范围的随机数,比如生成[10,20)区间内的随机整数、生成[0,50]区间内的随机整数。

Java内有两种实现伪随机数的方法,一种是java.util.Random(需要手动导入),另一种是Math.random

##1.基于Random类

import java.util.Random;

/**
 * Created by Administrator on 2016/11/26.
 */
public class Ram {
	public static void main(String[] args){
		Random b = new Random(20);
		int a = b.nextInt(51);
		while (a != 50){
			a = b.nextInt(51);
			System.out.println(a);
			if (a == 50){
				System.out.println("Hell yeah");
			}
		}
		System.out.println(a);
	}
}

解释下:在实例化时的20只是作为一个种子,种子数只是随机算法的起源数字,和生成的随机数的区间没有任何关系,如果没有指定数字,则使用系统时间作为种子

nextInt或者nextDouble是指定一个数的最大范围,但不包括这个数,上面的代码生成的是[0,50]的整数,输出的仅是为了方便查看结果

##2.基于后者

/**
 * Created by Administrator on 2016/11/27.
 */
public class Ram1 {
	public static void main(String[] args){
		int a = (int)(Math.random()*51);
		while (a != 50){
			a = (int)(Math.random()*51);
			System.out.println(a);
			if (a == 50){
				System.out.println(a);
				break;
			}
		}
		System.out.println(a);
	}
}

random()会生成一个[0,1)内的浮点数,如果你想生成[0,50]的整数,你需要在Math.random()后乘51,再进行显式转换。如果你想把区间收缩,比如[10,50],你需要在乘41后再加10,这样,最小的数值就是10,而最大的数值不会超过51,显式转换后就会是50

下面的代码是用random函数来生成[10,20)里的随机数:

public class Ram1 {
	public static void main(String[] args){
		for(int i = 0;i < 15;i++){
			int a = (int)(Math.random()*10+10);
			System.out.println(a);
		}
	}
}

输出的结果:

19
19
12
18
10
13
16
18
11
10
10
16
14
15
19

另一种实现:

import java.util.Random;

/**
 * Created by Administrator on 2016/11/26.
 */
public class Ram {
	public static void main(String[] args){
		Random b = new Random();
		for(int i = 0;i < 15;i++){
			int a = b.nextInt(10)+10;
			System.out.println(a);
		}
	}
}

两种方案都相当接近,使用时视情况选择吧,就酱

##一篇比较好的参考 随机数

c – 无法为整数生成全范围的随机数

c – 无法为整数生成全范围的随机数

我试图生成一个介于0和100 000之间的10000个整数的文件,所以我可以在以后对它们进行MergeSort.

当我使用fstream生成文件时,我从未得到超过32760的整数.

下面的方法生成文件,然后将其读回并检查32750以上的任何整数.我通常在32750和32760之间得到3-5个整数.为什么会发生这种情况,我该如何解决?是种子问题还是随机函数的实际使用?

// sizeOfArray = 10000
void generateFile() {
    ofstream fout("unsorted.txt");
    srand(time(NULL));

    // Generating the file
    int num;
    for(int i = 0; i < sizeOfArray; i++) {
         num = rand() % 100000;
         if(i < sizeOfArray-1)
            //fout << i+1 << ": " << num << endl;
            fout << num << endl;
         else
            //fout << i+1 << ": " << num;
            fout << num;
    }

    // Reading the File Back
    ifstream fin("unsorted.txt");
    for(int i = 0; i < sizeOfArray; i++) {
        fin >> num;
        if(num > 32750)
            cout << num << endl;
    }

    cin.get();
}

解决了
使用下面提供的答案,我生成了500次文件
我收到的最高整数为99931.

解决方法

可以从rand()获得的最高随机值是RAND_MAX,这是一个依赖于库的常量.在您的情况下,它似乎设置为2 ^ 15-1,这是符合有符号16位整数的最高正数.

当您需要生成大于RAND_MAX的数字时,请多次调用rand(),每次乘以RAND_MAX.例如,在您的情况下,以下代码应该工作(我假设您的int有32位):

num = rand();
num *= RAND_MAX;
num += rand();
num %= 100000;

注意,仅仅将三个随机数加在一起以获得期望的范围将不会产生与乘法和加法相同的随机分布.

ios – 在Swift 3.0中生成随机字节

ios – 在Swift 3.0中生成随机字节

我想在 Swift 3.0中使用SecRandomcopyBytes生成随机字节.这是我在Swift 2.2中的表现
private static func generaterandomBytes() -> String? {
    let data = NSMutableData(length: Int(32))

    let result = SecRandomcopyBytes(kSecRandomDefault,32,UnsafeMutablePointer<UInt8>(data!.mutableBytes))
    if result == errSecSuccess {
        return data!.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
    } else {
        print("Problem generating random bytes")
        return nil
    }
}

在Swift 3中,我尝试这样做,因为我知道unsafemutablebytes的概念现在不同了,但它不允许我返回.如果我注释掉返回部分,它仍然说无法推断通用参数ResultType

fileprivate static func generaterandomBytes() -> String? {
    var keyData = Data(count: 32)
    _ = keyData.withUnsafeMutableBytes {mutableBytes in
        let result = SecRandomcopyBytes(kSecRandomDefault,keyData.count,mutableBytes)
        if result == errSecSuccess {
            return keyData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
        } else {
            print("Problem generating random bytes")
            return nil
        }
    }
    return nil
}

有谁知道如何解决这一问题?

谢谢

解决方法

你很接近,但在关闭内部返回
从封闭,而不是从外部功能.
因此,只应在中调用SecRandomcopyBytes()
关闭,结果传回来.
func generaterandomBytes() -> String? {

    var keyData = Data(count: 32)
    let result = keyData.withUnsafeMutableBytes {
        (mutableBytes: UnsafeMutablePointer<UInt8>) -> Int32 in
        SecRandomcopyBytes(kSecRandomDefault,mutableBytes)
    }
    if result == errSecSuccess {
        return keyData.base64EncodedString()
    } else {
        print("Problem generating random bytes")
        return nil
    }
}

对于“单表达闭包”,闭包类型可以推断
自动,所以这可以缩短为

func generaterandomBytes() -> String? {

    var keyData = Data(count: 32)
    let result = keyData.withUnsafeMutableBytes {
        SecRandomcopyBytes(kSecRandomDefault,$0)
    }
    if result == errSecSuccess {
        return keyData.base64EncodedString()
    } else {
        print("Problem generating random bytes")
        return nil
    }
}

ios – 在Swift中生成一个随机单词

ios – 在Swift中生成一个随机单词

我正在尝试探索 Swift编程语言.我正在搜索 Swift API,我找到了UIReferenceLibraryViewController类.如果一个单词是真的(.dictionaryHasDeFinitionForTerm),我找到了返回bool值的方法,并且我还找到了一个可以返回一个随机单词的方法.

可悲的是,这种方法似乎并不存在.我意识到我可以探索第三方API,但是如果可能的话,我宁愿远离它们.

我想也许我可以通过所有字母的随机排列,然后检查它们是否形成一个真实的单词,但这似乎……好吧……愚蠢.

有人知道生成随机单词的方法吗?

我也不想手动制作数千个单词的长列表,因为我担心内存错误.我想尝试学习一些语法和新方法,而不是如何导航列表.

解决方法

我的/usr/share / dict / words文件是一个符号链接到/usr/share / dict / words / web2,Webster的第二国际词典,从1934年开始.文件只有2.4mb,所以你不应该看到太多的性能命中将整个内容加载到内存中.

这是我写的一个小的Swift 3.0代码片段,用于从字典文件中加载一个随机字.请记住在运行之前将文件复制到应用程序的包中.

if let wordsFilePath = Bundle.main.path(forResource: "web2",ofType: nil) {
    do {
        let wordsstring = try String(contentsOfFile: wordsFilePath)

        let wordLines = wordsstring.components(separatedBy: .newlines)

        let randomLine = wordLines[numericCast(arc4random_uniform(numericCast(wordLines.count)))]

        print(randomLine)

    } catch { // contentsOfFile throws an error
        print("Error: \(error)")
    }
}

Swift 2.2:

if let wordsFilePath = NSBundle.mainBundle().pathForResource("web2",ofType: nil) {
    do {
        let wordsstring = try String(contentsOfFile: wordsFilePath)

        let wordLines = wordsstring.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())

        let randomLine = wordLines[Int(arc4random_uniform(UInt32(wordLines.count)))]

        print(randomLine)

    } catch { // contentsOfFile throws an error
        print("Error: \(error)")
    }
}

Swift 1.2片段:

if let wordsFilePath = NSBundle.mainBundle().pathForResource("web2",ofType: nil) {

    var error: NSError?

    if let wordsstring = String(contentsOfFile: wordsFilePath,encoding: NSUTF8StringEncoding,error: &error) {

        if error != nil {
            // String(contentsOfFile: ...) Failed
            println("Error: \(error)")
        } else {
            let wordLines = wordsstring.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())

            let randomLine = wordLines[Int(arc4random_uniform(UInt32(wordLines.count)))]

            print(randomLine)
        }
    }
}

关于如何在Swift中生成大范围的随机数?如何在swift中生成大范围的随机数数据的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于#随机数#生成指定范围的随机数、c – 无法为整数生成全范围的随机数、ios – 在Swift 3.0中生成随机字节、ios – 在Swift中生成一个随机单词等相关知识的信息别忘了在本站进行查找喔。

本文标签: