Câu hỏi Porting std :: bản đồ đến C?


Tôi đang chuyển một số mã c ++ sang c. Một tương đương khả thi của std :: map in c? Tôi biết không có tương đương trong c.

Đây là những gì tôi đang nghĩ đến việc sử dụng:

Trong c ++:

std::map< uint, sTexture > m_Textures;

Trong c:

typedef struct
{
  uint* intKey;
  sTexture* textureValue;
} sTMTextureMap;

Liệu điều đó có khả thi hay tôi đơn giản hóa bản đồ quá nhiều? Chỉ trong trường hợp bạn không có được mục đích của nó là Texture Map.


18
2018-03-15 01:11


gốc


uthash "một bảng băm dễ sử dụng cho các cấu trúc C". <br> qua: http://en.wikipedia.org/wiki/Hash_table - Functastic


Các câu trả lời:


Nhiều triển khai C hỗ trợ tsearch (3) hoặc hsearch (3). tsearch (3) là một cây nhị phân và bạn có thể cung cấp một cuộc gọi so sánh. Tôi nghĩ rằng đó là về gần như bạn đang đi để có được một std :: bản đồ.

Dưới đây là một số mã ví dụ c99

#include <search.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef struct
{
      int key;
      char* value;
} intStrMap;

int compar(const void *l, const void *r)
{
    const intStrMap *lm = l;
    const intStrMap *lr = r;
    return lm->key - lr->key;
}

int main(int argc, char **argv)
{
    void *root = 0;

    intStrMap *a = malloc(sizeof(intStrMap));
    a->key = 2;
    a->value = strdup("two");
    tsearch(a, &root, compar); /* insert */

    intStrMap *find_a = malloc(sizeof(intStrMap));
    find_a->key = 2;

    void *r = tfind(find_a, &root, compar); /* read */
    printf("%s", (*(intStrMap**)r)->value);

    return 0;
}

22
2018-03-15 02:18



cảm ơn, tsearch rất tuyệt. - markus_p
@matt_h tôi có thể sử dụng nó với một char [] như là một chìa khóa? - Giuseppe
chắc chắn, bạn chỉ cần viết so sánh bằng cách sử dụng một cái gì đó như 'strcmp (lm-> key, lr-> key)' - matt_h


Tại sao bạn không chỉ quấn một giao diện C xung quanh std::map? Tức là viết một vài hàm C ++ trong mô-đun riêng của chúng:

typedef std::map<int, char*> Map;

extern "C" {

void* map_create() {
  return reinterpret_cast<void*> (new Map);
}

void map_put(void* map, int k, char* v) {
  Map* m = reinterpret_cast<Map*> (map);
  m->insert(std::pair<int, char*>(k, v));
}

// etc...

} // extern "C"

Và sau đó liên kết với ứng dụng C của bạn.


11
2017-10-01 15:19





Đó chắc chắn là một thực hiện có thể. Bạn có thể muốn xem xét cách bạn sẽ triển khai lập chỉ mục và tác động hiệu suất nào sẽ có. Ví dụ, bạn có thể có danh sách intKey là danh sách các khóa được sắp xếp. Tìm kiếm một khóa sẽ là thời gian O (log N), nhưng chèn một mục mới sẽ là O (N).

Bạn có thể thực hiện nó như một cái cây (như std :: map), và sau đó bạn sẽ có O (log N) chèn và tra cứu.

Một giải pháp thay thế khác là triển khai nó như một bảng băm, có hiệu suất thời gian chạy tốt hơn, giả sử một hàm băm tốt và một mảng intKey đủ thưa thớt.


5
2018-03-15 01:30



có bất kỳ dự án mã nguồn mở nào thực hiện những triển khai này mà bạn nói không? - kthakore
một thực thi cây đọc màu đen tốt đẹp là một trong OpenBSD. Nó phù hợp trong một tệp tiêu đề duy nhất và có thể được sử dụng cho bất kỳ cấu trúc nào. Xem openbsd.org/cgi-bin/cvsweb/src/sys/sys/tree.h - quinmars


Bạn có thể thực hiện nó tuy nhiên bạn chọn. Nếu bạn sử dụng cách tiếp cận danh sách liên kết, việc chèn của bạn sẽ là O (1) nhưng việc truy xuất và xóa của bạn sẽ là O (n). Nếu bạn sử dụng một cái gì đó phức tạp hơn như một cây màu đỏ-đen, bạn sẽ có hiệu suất trung bình tốt hơn nhiều.

Nếu bạn đang thực hiện nó cho mình danh sách liên kết có lẽ là dễ nhất, nếu không lấy một số được cấp giấy phép hợp pháp màu đỏ-đen hoặc loại khác của cây từ internet sẽ là lựa chọn tốt nhất. Thực hiện cây đỏ-đen của riêng bạn không được khuyến khích ... Tôi đã làm điều này và không muốn làm điều đó một lần nữa.

Và để trả lời một câu hỏi mà bạn không hỏi: có lẽ bạn nên xem xét lại xem việc chuyển sang C từ C ++ có thực sự cung cấp tất cả những lợi ích bạn muốn hay không. Chắc chắn có những tình huống mà nó có thể cần thiết, nhưng không có nhiều.


3
2018-03-15 02:08





Tôi đã thử triển khai bản đồ trong C, dựa trên khoảng trống *

http://code.google.com/p/cstl/

Đó là công việc đang diễn ra, nhưng bản đồ đã hoàn tất.

http://code.google.com/p/cstl/source/browse/src/c_map.c

Nó được viết dựa trên Red Black Tree.


2
2018-04-12 13:41





Không có thư viện chuẩn nào trong C cung cấp chức năng tương tự như bản đồ. Bạn sẽ cần phải triển khai chức năng giống như bản đồ của mình bằng cách sử dụng một số hình thức chứa có hỗ trợ truy cập các phần tử thông qua các khóa.


0
2018-03-15 01:13



Tôi biết tôi hỏi bạn có biết cách sử dụng tốt không? - kthakore


người đàn ông dbopen

Cung cấp NULL làm đối số tệp và nó sẽ là vùng chứa chỉ trong bộ nhớ cho dữ liệu khóa / giá trị.

Ngoài ra còn có các giao diện thư viện cơ sở dữ liệu Berkeley khác nhau với chức năng khóa / giá trị tương tự (dbm của người đàn ông, kiểm tra BerkeleyDB từ Sleepycat, thử một số tìm kiếm, v.v.).


0
2018-03-15 01:46



dường như quá mức cần thiết để tạo họa tiết ... - kthakore