我是靠谱客的博主 留胡子白开水,这篇文章主要介绍d的按列赋值数组,现在分享给大家,希望可以做个参考。

原文
对:

复制代码
1
2
byte[3][3] myArr;

可:

复制代码
1
2
myArr[0] = 5;

并有了:

复制代码
1
2
3
4
5,5,5 0,0,0 0,0,0

可类似赋值列吗?myArr[][0] = 5没用.
所有的东西,都在内存中且是并排的,示例(类似数组)涵盖了该问题:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import std.stdio; void main() { int[COL][ROW] sample = [ [ 5, 5, 5 ], [ 0, 0, 0 ], [ 0, 0, 0 ], ]; auto arrayish = Arrayish!int(ROW, COL); assert(arrayish.length == SUM); // 复制数组.. foreach(r; 0..ROW) { foreach(c; 0..COL) { arrayish[r, c] = sample[r][c]; } } arrayish.print(); foreach(n; 0..COL) { //arrayish.columnMajor(n).writeln;/* arrayish[n].writeln;//*/ } // 清理并设置.. arrayish.elements[] = 0; foreach(r; 0..ROW) arrayish[r] = 5; arrayish.print(); } struct Arrayish(T) { private { T[] elements; const size_t row, col; } this(size_t row, size_t col) { this.elements = new T[row * col]; this.row = row; this.col = col; } ref T opIndex(size_t row = 0, size_t col = 0) { return elements[row * this.col + col]; } ref T columnMajor(size_t row = 0, size_t col = 0) { return elements[col * this.row + row]; } auto length() { return row * col; } void print() { foreach(r; 0..row) { foreach(c; 0..col) this[r, c].write; writeln; } } } /* 打印: 555 000 000 5 0 0 500 500 500 */

我突然想到一个想法,它不影响处理器逐页从堆请求内存的速度,但会受到限制.

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import std.stdio, std.algorithm, std.range; enum : size_t { ROW = 11, COL = 4, SUM = ROW * COL } void main() { // 4 正短 x 11 正长: auto arr = LimitedArray!COL(ROW); assert(arr.cell[0].elements.length >= COL); assert(arr.length == SUM); alias T = typeof(arr.cell[0].elements[0]); auto range = iota!T(T.max/2, T.max, 762).array; assert(range.length == SUM); range.each!((i, T x) => arr[i] = x);/* foreach(i, x; range) { arr[i] = x; writeln(x); }//*/ arr.print; // 8 正字节 x 99 正长: auto minMaxTest = LimitedArray!8(99); auto testLength = minMaxTest.length; minMaxTest[0] = ubyte.min + 1; minMaxTest[testLength - 1] = ubyte.max; minMaxTest.print; } template LimitedArray(size_t col) { enum error = "容量错误"; enum size = (col + 1) >> 1; static if(size >= 3) { alias T = ubyte; // 最小值,但最大列 } else static if(size == 2) { alias T = ushort;// 平均数组 } else static if(size == 1) { alias T = uint; // 最大值,但最小列 } enum s = ulong.sizeof/T.sizeof; struct LimitedArray { invariant(uint.sizeof > size, error); private { union Cell { ulong element; T[s] elements; } Cell[] cell; const size_t row; } this(size_t row) { this.cell = new Cell[row]; this.row = cell.length; } ref T opIndex(size_t i) in(i < length, "区间溢出") { auto len = cell.length; size_t y, x = i % len;y = i / len; return cell[x].elements[y]; } auto length() { return row * col; } void print() { foreach(i, c; cell) { i.writef!"row %2s =>"; foreach(e; c.elements) e.writef!"%6s"; writeln(": ", c.element); } } } }

下面是使用标准库函数的方法:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import std.range: transversal; import std.algorithm: map, fill; import std.stdio: writefln; void main() { byte[3][3] myArr; myArr[] .map!((ref row) => row[]) .transversal(0) .fill(byte(5)); writefln("%(%sn%)", myArr[]); }

这里唯一技巧是调用映射(map),为把行类型字节[3](不是区间类型)改为字节[](这是区间).
一旦完成了,transversal(0)(转置)每行中在0索引处遍历(即,迭代第一列),并用指定值填充设置这些项中每一项.

启用了优化LDC编译起来非常高效,可内联所有区间函数并展开循环:这里

感谢贡献,这样才有比较机会,下面可看到,用union实现的LimitedArray结构快了15~20倍.

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import std.stdio, std.algorithm, std.range; import std.datetime.stopwatch; enum set { COL = 8, ROW = 65535 } void main() { ubyte[set.COL][set.ROW] sArray; auto lArray = LimitedArray!(set.COL)(set.ROW); auto ds = [ Duration.zero, Duration.zero ]; auto sw = StopWatch(AutoStart.yes); //#line 1 sArray[].map!((ref row) => row[]).transversal(0).fill(byte.max); ds[0] = sw.peek(); //#line 2 lArray.cell.each!((ref c) => c.elements[0] = byte.max); sw.stop(); /* sArray.writefln!"%(%sn%)"; lArray.print();//*/ writefln!"#line1 %s μs"(ds[0].total!"usecs"); ds[1] = sw.peek - ds[0]; writefln!"#line2 %s μs"(ds[1].total!"usecs"); "Percent %".writeln(ds[0]/ds[1]); } /* #line1 3362 μs #line2 233 μs Percent %14 */

最后

以上就是留胡子白开水最近收集整理的关于d的按列赋值数组的全部内容,更多相关d内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部