朱莉娅:如何获得给定字符串s的随机排列?

时间:2017-10-28 15:32:04

标签: string julia permutation

我想到了两种不同的方式,但两者看起来都很难看。

  1. 通过s将字符串a转换为数组split,然后再将sample(a, length(s), replace=false)join数组再次转换为字符串

  2. 获取RandomPermutation r length(s) join s[i] i r sample(::String, ::Int64; replace=false) <P style="color: white;font-size: 2.2em" class="w3-center"><span style="font- size: 1.2em">Nadia</span>About<span style="font-size: 1.2em">Contact</span> </P>

  3. 什么是正确的方法?不幸的是,没有匹配(function() { var inputNumber = document.getElementById('inputNumber').value; var validateBtn = document.getElementsByTagName("a"); //a surrounding n button var linkValidation = validateBtn[0].href = ("https://checkyournumber.com.action?inputNumber=" + inputNumber ); }); 的方法。

4 个答案:

答案 0 :(得分:4)

shuffle定义String方法可能会构成盗版类型,但无论如何,这是一个建议的实现:

Base.shuffle(s::String) = isascii(s) ? s[randperm(end)] : join(shuffle!(collect(s)))

答案 1 :(得分:2)

如果您想从shuffle中挤出效果,那么您可以考虑:

function shufflefast(s::String)
    ss = sizeof(s)
    l = length(s)

    ss == l && return String(shuffle!(copy(Vector{UInt8}(s))))

    v = Vector{Int}(l)
    i = start(s)
    for j in 1:l
        v[j] = i
        i = nextind(s, i)
    end

    p = pointer(s)
    u = Vector{UInt8}(ss)
    k = 1
    for i in randperm(l)
        for j in v[i]:(i == l ? ss : v[i+1]-1)
            u[k] = unsafe_load(p, j)
            k += 1
        end
    end
    String(u)
end

对于大字符串,ASCII速度快4倍,UTF-8速度快3倍。

不幸的是它很乱 - 所以我宁愿把它当成一种练习。但是,它只使用导出的函数,所以它不是黑客。

答案 2 :(得分:1)

受到Bogumil Kaminski的答案中的优化技巧的启发,以下版本具有几乎相同的性能,但更清晰(在我看来)并使用可能本身有价值的第二个效用函数:

function strranges(s)      # returns the ranges of bytes spanned by chars
    u = Vector{UnitRange{Int64}}()
    sizehint!(u,sizeof(s))
    i = 1
    while i<=sizeof(s)
        ii = nextind(s,i)
        push!(u,i:ii-1)
        i = ii
    end
    return u
end

function shufflefast(s)
    ss = convert(Vector{UInt8},s)
    uu = Vector{UInt8}(length(ss))
    i = 1
    @inbounds for r in shuffle!(strranges(s))
        for j in r
            uu[i] = ss[j]
            i += 1
        end
    end
    return String(uu)
end

时间示例:

julia> using BenchmarkTools

julia> s = "ďaľšý"

julia> @btime shuffle($s)       # shuffle from DNF's answer
  831.200 ns (9 allocations: 416 bytes)
"ýľďša"

julia> @btime shufflefast($s)   # shuffle from this answer
  252.224 ns (5 allocations: 432 bytes)
"ľýďaš"

julia> @btime kaminskishufflefast($s)  # shuffle from Kaminski's answer
  197.345 ns (4 allocations: 384 bytes)
"ýašďľ"

答案 3 :(得分:0)

编辑:性能稍好一点 - 请参阅代码注释

这是来自Bogumil Kaminski的答案,我试图避免计算长度(*),如果没有必要:

function shufflefast2(s::String)
    ss = sizeof(s)
    local l

    for l in 1:ss
        #if ((codeunit(s,l) & 0xc0) == 0x80)
        if codeunit(s,l)>= 0x80  # edit (see comments bellow why)
            break
        end
    end

    ss == l && return String(shuffle!(copy(Vector{UInt8}(s))))

    v = Vector{Int}(ss)
    i = 1
    l = 0
    while i<ss
        l += 1
        v[l] = i
        i = nextind(s, i)
    end
    v[l+1] = ss+1  # edit - we could do this because ss>l

    p = pointer(s)
    u = Vector{UInt8}(ss)
    k = 1
    for i in randperm(l)
        # for j in v[i]:(i == l ? ss : v[i+1]-1)
        for j in v[i]:v[i+1]-1  # edit we could do this because v[l+1] is defined (see above)
            u[k] = unsafe_load(p, j)
            k += 1
        end
    end
    String(u)
end

ascii string的示例时间:

julia> srand(1234);@btime for i in 1:100 danshufflefast("test") end
  19.783 μs (500 allocations: 34.38 KiB)

julia> srand(1234);@btime for i in 1:100 bkshufflefast("test") end
  10.408 μs (300 allocations: 18.75 KiB)

julia> srand(1234);@btime for i in 1:100 shufflefast2("test") end
  10.280 μs (300 allocations: 18.75 KiB)

差异太小,有时bkshufflefast更快。表现必须是平等的。整个长度必须计数,并且有相同的分配。

unicode字符串的示例时间:

julia> srand(1234);@btime for i in 1:100 danshufflefast(s) end
  24.964 μs (500 allocations: 42.19 KiB)

julia> srand(1234);@btime for i in 1:100 bkshufflefast(s) end
  20.882 μs (400 allocations: 37.50 KiB)

julia> srand(1234);@btime for i in 1:100 shufflefast2(s) end
  19.038 μs (400 allocations: 40.63 KiB)

shufflefast2虽然有点但显然更快。比Bogumil的功能多一点分配,比Dan的解决方案少一点。

(*) - 我有点希望Julia中的String实现将来会更快,而且长度可能比现在快得多。