我想到了两种不同的方式,但两者看起来都很难看。
通过s
将字符串a
转换为数组split
,然后再将sample(a, length(s), replace=false)
和join
数组再次转换为字符串
获取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>
什么是正确的方法?不幸的是,没有匹配(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 );
});
的方法。
答案 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实现将来会更快,而且长度可能比现在快得多。