const std = @import("std");
/// 柔性数组实现
/// `var arr = FlexArray(i64).init(allocator);`
pub fn FlexArray(comptime T: type) type {
return struct {
pos: u64,
allocator: std.mem.Allocator,
array: []T,
const Self = @This();
pub fn init(allocator: std.mem.Allocator) anyerror!Self {
return .{ .pos = 0, .allocator = allocator, .array = try allocator.alloc(T, 1 << 2) };
}
pub fn deinit(self: Self) void {
self.allocator.free(self.array);
}
pub fn append(self: *Self, value: T) anyerror!void {
const pos = self.pos;
const capacity = self.array.len;
if (pos == capacity) {
const larger = try self.allocator.alloc(T, capacity << 1);
@memcpy(larger[0..capacity], self.array);
self.allocator.free(self.array);
self.array = larger;
}
self.array[pos] = value;
self.pos = pos + 1;
}
pub fn get(self: Self, index: u64) anyerror!T {
// index 是否越界
if (index >= self.pos) return error.IndexOutOfBounds;
return self.array[index];
}
pub fn remove(self: *Self, index: u64) anyerror!void {
const pos = self.pos;
if (index >= pos) return error.IndexOutOfBounds;
var current = index + 1;
while (current < pos) : (current += 1) {
self.array[current - 1] = self.array[current];
}
self.pos -= 1;
}
pub fn reverse(self: *Self) void {
const pos = self.pos;
if (self.array.len == 0) return;
var start: u64 = 0;
var end = pos - 1;
while (start < end) {
if (self.array[start] != self.array[end]) {
self.array[start] = self.array[start] ^ self.array[end];
self.array[end] = self.array[start] ^ self.array[end];
self.array[start] = self.array[start] ^ self.array[end];
}
start += 1;
end -= 1;
}
}
};
}
const testing = std.testing;
test "Test Flex Array" {
// 新建
const allocator = std.testing.allocator;
var arr = try FlexArray(i64).init(allocator);
defer arr.deinit();
for (0..33) |value| {
try arr.append(@intCast(value));
}
try testing.expectEqual(@as(usize, 64), arr.array.len);
try testing.expectEqual(@as(i64, 12), arr.get(12));
try testing.expectEqual(@as(i64, 22), arr.get(22));
try testing.expectError(error.IndexOutOfBounds, arr.remove(66));
try arr.remove(11);
try testing.expectEqual(@as(i64, 12), arr.get(11));
try testing.expectEqual(@as(u64, 32), arr.pos);
try arr.remove(0);
try testing.expectEqual(@as(i64, 1), arr.get(0));
arr.reverse();
try testing.expectEqual(@as(u64, 31), arr.pos);
try testing.expectEqual(@as(i64, 1), arr.get(arr.pos - 1));
try testing.expectEqual(@as(i64, 2), arr.get(arr.pos - 2));
try testing.expectEqual(@as(i64, 23), arr.get(arr.pos - 22));
}
【ZIG】实现简单可变数组
最新推荐文章于 2024-06-09 14:32:01 发布