Julia程序设计3 数组2 排序、复制、集合运算、字典

史鹏云
2023-12-01

排序

1、Julia中数组排序最基础的函数是sort,它默认是从小到大排序,如果加上rev = true就是从大到小:

julia> a = [2,6,3,4,1,7,8,5]
8-element Array{Int64,1}:
 2
 6
 3
 4
 1
 7
 8
 5

julia> sort(a)
8-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
 8

julia> sort(a, rev = true)
8-element Array{Int64,1}:
 8
 7
 6
 5
 4
 3
 2
 1

2、用sortperm()可以返回按从小打到排列的元素的指标,比如a中1在第5位,2在第一位,那么sortperm就会返回5,1,。。。

julia> I = sortperm(a)
8-element Array{Int64,1}:
 5
 1
 3
 4
 8
 2
 6
 7

julia> a[I] # 将a中的元素按I的顺序还原
8-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
 8

3、sort中加上by = abs可以按绝对值从小到大排序,by = 和rev = 可以一起用;事实上 by = 可以接任何实值函数,比如 by = sin,by = exp或者自定义函数

julia> b = [9,-3,0,4,-5]
5-element Array{Int64,1}:
  9
 -3
  0
  4
 -5

julia> sort(b, by = abs)
5-element Array{Int64,1}:
  0
 -3
  4
 -5
  9

julia> sort(b, by = abs, rev = true)
5-element Array{Int64,1}:
  9
 -5
  4
 -3
  0

julia> sort(b, by = sin)
5-element Array{Int64,1}:
  4
 -3
  0
  9
 -5

4、多维数组排序需要指定维数:

julia> A = [[1,4,3] [2,6,8] [4,4,7]]
3×3 Array{Int64,2}:
 1  2  4
 4  6  4
 3  8  7

julia> sort(A, dims = 1) # 逐行排序
3×3 Array{Int64,2}:
 1  2  4
 3  6  4
 4  8  7

julia> sort(A, dims = 2) # 逐列排序
3×3 Array{Int64,2}:
 1  2  4
 4  4  6
 3  7  8

排序算法

Julia的默认排序方法是插入排序(insertion sort),快速排序(quick sort)和归并排序(merge sort),后两者分别是默认的数值与非数值元素的排序方法。插入排序复杂度是 O ( n 2 ) O(n^2) O(n2),后两者复杂度是 O ( n ln ⁡ n ) O(n\ln n) O(nlnn),但通常快速排序比归并排序还要快一点。插入排序与归并排序是稳定的排序方法,但快速排序不稳定,相等的元素可能有不同的排序。用alg = 可以选择排序方法,@time 可以计时并记录内存分配:

julia> A = randn(Float64,10000);
julia> @time sort(A;alg=InsertionSort)
  0.066310 seconds (94.03 k allocations: 4.919 MiB)

julia> @time sort(A;alg=QuickSort);
  0.062647 seconds (93.39 k allocations: 4.804 MiB)

julia> @time sort(A;alg=MergeSort);
  0.068424 seconds (85.44 k allocations: 4.495 MiB)

时间上最优的是快速排序,但它需要的内存比归并排序多一点。

查找数组中的元素

1、用in判断某个元素是否在数组中:

julia> A = [1,2,3,4]
4-element Array{Int64,1}:
 1
 2
 3
 4

julia> B = [A A]; # B的数据类型是4×2 Array{Int64,2},是一个二维的数组
julia> C = [1,2]; # C是数组的切片A[1:2]
julia> D = [A,A]; # D的数据类型是2-element Array{Array{Int64,1},1},即以数组为元素的数组

julia> 1 in A # 判断元素是否在数组中的两种方法
true
julia> in(1,A)
true

julia> C in A # A的切片不是A的元素
false

julia> A in B # 低维数组即使与高维数组某一维相同,它也不是高维数组的元素
false

julia> A in D # 数组可以是以数组为元素的数组的元素
true

2、查找数组中符合某种条件的元素,有findmin findmax findall findprev findnext findmin! findmax! findlast findfirst这些函数可以用,这里介绍前三种,其他的可以自己help

julia> A = [3,5,6,1,7,-2]

julia> findmin(A) # 找最小值,返回值第一个是最小值,第二个是最小值的位置
(-2, 6)

julia> findmax(A) # 找最大值,返回值第一个是最大值,第二个是最大值的位置
(7, 5)

julia> findall(x->x>=0,A) # 找符合条件的元素,并返回元素的位置,x->表示寻找的元素满足后面的条件
5-element Array{Int64,1}:
 1
 2
 3
 4
 5

复制数组

Julia中数组的复制有两种形式:浅复制copy()和深复制deepcopy()。浅复制得到的新的数组会随原来的数组的改变而改变,深复制得到的数组不会随原来的数组的改变而改变:

julia> a = zeros(3,3)
3×3 Array{Float64,2}:
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0

julia> b = [1,2,a]
3-element Array{Any,1}:
 1
 2
  [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

julia> c = copy(b); d = deepcopy(b); # c为浅复制,d为深复制

julia> b[3][1]=10 # 改变b的值
10

julia> b
3-element Array{Any,1}:
 1
 2
  [10.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

julia> c # c的值随之改变
3-element Array{Any,1}:
 1
 2
  [10.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

julia> d # d的值不改变
3-element Array{Any,1}:
 1
 2
  [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

for语句实现数组的变换与生成

在[]中用for语句可以实现对数组的变换:

julia> A = [1,2,3,4]
4-element Array{Int64,1}:
 1
 2
 3
 4

julia> [A[i]^2 for i = 1:length(A)] # A中元素做平方运算,用A[i]表示A中元素
4-element Array{Int64,1}:
  1
  4
  9
 16

julia> [sqrt(n) for n in A] # A中元素做开方变换,与上面的区别是元素表示方法不同,这里用n表示A中元素
4-element Array{Float64,1}: 
 1.0
 1.4142135623730951
 1.7320508075688772
 2.0

julia> [complex(A[i],A[i+1]) for i=1:length(A)-1] # 多元的,非实值的变换也可以
3-element Array{Complex{Int64},1}:
 1 + 2im
 2 + 3im
 3 + 4im

julia> Float64[0.5*A[i]+0.333*A[i+1] for i=2:length(A)-1] # 还可以指定变换后的数据类型以及参与变换的元素范围
2-element Array{Float64,1}:
 1.999
 2.832

julia> collect(x^y for x in 1:3,y in 1:3) # 配合其他函数还可以用来创建数组
3×3 Array{Int64,2}:
 1  1   1
 2  4   8
 3  9  27

集合运算

集合的交并差在Julia中可以用union、intersect、setdiff来做:

julia> A = [1,2,3,4]
4-element Array{Int64,1}:
 1
 2
 3
 4

julia> B = [3,3,3,3]
4-element Array{Int64,1}:
 3
 3
 3
 3

julia> union(A,B)
4-element Array{Int64,1}:
 1
 2
 3
 4

julia> intersect(A,B)
1-element Array{Int64,1}:
 3

julia> setdiff(A,B)
3-element Array{Int64,1}:
 1
 2
 4

julia> setdiff(B,A)
0-element Array{Int64,1}

字典

字典可以理解成更一般的数组,数组体现的是从指标(UInt64)到数组的元素(任意数据类型)的对应关系,字典则用来描述更一般的数据类型之间的对应关系。

创建字典

字典的创建用Dict()函数,a=>b表示从a到b的对应关系,a是索引,b是字,一个字可以有多个索引,但一个索引只对应一个字;如果Dict()中不列举对应关系,创建的就是空字典;字典的数据类型由对应的数据类型决定:

julia> Dict("red"=>1,"blue"=>2,"green"=>3)
Dict{String,Int64} with 3 entries:
  "blue"  => 2
  "green" => 3
  "red"   => 1

julia> Dict("red"=>"Red","blue"=>"Red","green"=>"Green")
Dict{String,String} with 3 entries:
  "blue"  => "Red"
  "green" => "Green"
  "red"   => "Red"

julia> Dict{Integer,String}()
Dict{Integer,String} with 0 entries

julia> Dict()
Dict{Any,Any} with 0 entries

查阅字典

julia> dict = Dict('r'=>"Red",'b'=>"Blue",'g'=>"Green")
Dict{Char,String} with 3 entries:
  'g' => "Green"
  'r' => "Red"
  'b' => "Blue"

julia> dict['r']
"Red"

查看索引

julia> dict = Dict('r'=>"Red",'b'=>"Blue",'g'=>"Green")
Dict{Char,String} with 3 entries:
  'g' => "Green"
  'r' => "Red"
  'b' => "Blue"
  
julia> keys(dict) # 查看索引
Base.KeySet for a Dict{Char,String} with 3 entries. Keys:
  'g'
  'r'
  'b'

julia> values(dict) # 查看字
Base.ValueIterator for a Dict{Char,String} with 3 entries. Values:
  "Green"
  "Red"
  "Blue"

修改字典

julia> dict = Dict('r'=>"Red",'b'=>"Blue",'g'=>"Green")
Dict{Char,String} with 3 entries:
  'g' => "Green"
  'r' => "Red"
  'b' => "Blue"

julia> dict['b']="Black"
"Black"

julia> dict
Dict{Char,String} with 3 entries:
  'g' => "Green"
  'r' => "Red"
  'b' => "Black"

添加、删除

julia> dict = Dict('r'=>"Red",'b'=>"Blue",'g'=>"Green")
Dict{Char,String} with 3 entries:
  'g' => "Green"
  'r' => "Red"
  'b' => "Blue"
  
julia> dict['o'] ="Orange" # 把字赋值给新的索引就是添加新的对应
"Orange"

julia> dict
Dict{Char,String} with 4 entries:
  'g' => "Green"
  'r' => "Red"
  'o' => "Orange"
  'b' => "Blue"

julia> delete!(dict,'o') # 删除某个索引就可以删除一个对应
Dict{Char,String} with 3 entries:
  'g' => "Green"
  'r' => "Red"
  'b' => "Blue"
 类似资料: