【ZIG】实现简单可变数组

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));
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值