【问题标题】:Need help making an ArrayList Add At in C需要帮助在 C 中制作 ArrayList Add At
【发布时间】:2020-10-29 15:25:37
【问题描述】:

我不确定如何使用 arrlist_addat 在特定索引处添加列表。我包括了我的一些其他方法和我的结构,所以你可以看到我是怎么做的。如果添加它,该方法必须返回一个布尔值 true,如果它失败,则返回 false。

感谢您的帮助。

struct ArrayList {
    void** arr;
    int size;
    int maxSize;
    int itemSize;
    char* type;
};

struct ArrayList* arrlist_initialize(int maxSize, int itemSize, char* dataType) {
    struct ArrayList* list = malloc(sizeof(struct ArrayList));
    list->size = 0;
    list->maxSize = maxSize;
    list->itemSize = itemSize;
    list->type = dataType;
    list->arr = NULL;
    return list;
}

bool arrlist_add(struct ArrayList* list, void* element) {
    void** data = realloc(list->arr, sizeof(*list->arr));
    if (data == NULL)
        return false;
    data[list->size] = element;
    list->arr = data;
    list->size = list->size+1;
    return true;
}

bool arrlist_addat(struct ArrayList* list, int index, void* element) {

    //Need help here.

}

void* arrlist_get(struct ArrayList* list, int index) {
    void* value = list->arr[index];
    if (value != NULL)
        return value;
    return NULL;
}

int arrlist_index_of(struct ArrayList* list, void* element) {
    for (int i = 0; i < list->size; ++i) {
        if (element == arrlist_get(list, i))
            return i;
    }
    return -1;
}

【问题讨论】:

  • void** data = realloc(list-&gt;arr, sizeof(*list-&gt;arr)); 看起来很糟糕。应该是void** data = realloc(list-&gt;arr, sizeof(*list-&gt;arr) * (list-&gt;size + 1));
  • 1.在数组 2 的末尾添加一个虚拟元素(可能是 NULL)。将数组的元素移到插入点之后 3. 存储要插入的值
  • alist_get 用于arrlist_index_of() 此处未定义。你的意思是arrlist_get?
  • 是的,应该是 arrlist_get
  • arrlist_addat 应该插入一个元素(将现有元素向上移动一个索引)还是覆盖一个元素?另外,index 是否可以大于 list-size 需要插入额外的 NULL 元素?

标签: c arraylist add


【解决方案1】:

假设数组的长度为maxSize,你只需在插入元素前将元素向右移动即可,像这样:

bool arrlist_addat(struct ArrayList* list, int index, void* element)
{
    bool done;
    int i;

    assert(list != NULL);
    
    if ((list->size < list->maxSize) && (index >= 0) && (index <= list->size)) {
        /*make room for the new element*/
        for (i = list->size; i > index; i--) {
            list->arr[i] = list->arr[i - 1];
        }
        
        list->arr[index] = element;     
        list->size++;
        done = true;
    } else {
        done = false;
    } 
    return done;    
}

【讨论】:

    【解决方案2】:

    规定的要求是arrlist_addat 应该在给定索引处插入一个不能大于当前大小的元素。因此,在检查要求后,该函数只需要重新分配保存void * 值的数组/列表的内存,将给定索引中的void * 值加一,并设置写入插入的void *索引位置的值。

    假设实现具有优化的memmove 函数,这可能是对现有元素进行洗牌的最快方法。这是一个示例实现:

    bool arrlist_addat(struct ArrayList* list, int index, void* element) {
        void** data;
        if (index > list->size)
            return false;
        data = realloc(list->arr, sizeof(*list->arr) * (list->size + 1));
        if (!data)
            return false;
        memmove(&list->arr[index + 1], &list->arr[index], (list->size - index) * sizeof(*list->arr));
        list->arr[index] = element;
        list->size++;
        return true;
    }
    

    arrlist_add可以使用arrlist_addat实现:

    bool arrlist_add(struct ArrayList* list, void* element) {
        return arrlist_addat(list, list->size, element);
    }
    

    ASIDE:arrlist_get 应该检查索引并在超出范围时返回 NULL:

    void* arrlist_get(struct ArrayList* list, int index) {
        if (index >= list->index)
            return NULL;
        // Should we also check for negative indices here?
        // It's probably better to use unsigned indices anyway!
        return list->arr[index];
    }
    

    【讨论】:

    • 我忽略了list-&gt;maxSize,因为原始代码也忽略了它。但如果需要,添加超过list-&gt;maxSize 的检查很容易。
    • 在您的实现中,成功时结果未定义。
    • @AugustKarlstrom 谢谢。最后我忘记了return true;。我现在补充一下。
    • 如果您使用例如 GCC 编译器,标志 -Wall 将捕捉到这一点。
    • @AugustKarlstrom 问题是,我没有费心去编译它。 :)
    猜你喜欢
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 2014-06-27
    相关资源
    最近更新 更多