• glib 散列表


    原文地址: http://hi.baidu.com/study_together/blog/item/7db6da1d7acfbbf91ad5763e.html

    编译:gcc -g -Wall -O0 fuck.c -o fuck `pkg-config --libs --cflags glib-2.0`

    1

     一些简单的散列表操作     有错误需要调试

    这里是一些示例,可以生动地展示以上的理论:

    #include <glib.h>
    #include
    <stdio.h>

    int main(int argc, char** argv) {
    GHashTable
    * hash = g_hash_table_new(g_str_hash, g_str_equal);
    g_hash_table_insert(hash,
    "Virginia", "Richmond");
    g_hash_table_insert(hash,
    "Texas", "Austin");
    g_hash_table_insert(hash,
    "Ohio", "Columbus");
    printf(
    "There are %d keys in the hash\n", g_hash_table_size(hash));
    printf(
    "The capital of Texas is %s\n", g_hash_table_lookup(hash, "Texas"));
    gboolean found
    = g_hash_table_remove(hash, "Virginia");
    printf(
    "The value 'Virginia' was %sfound and removed\n", found ? "" : "not ");
    g_hash_table_destroy(hash);
    return 0;
    }

    ***** Output *****

    There are 3 keys in the hash
    The capital of Texas is Austin
    The value 'Virginia' was found and removed

    2

    插入和替换值

    当使用 g_hash_table_insert 插入键时,GHashTable 首先检查那个键是否已经存在。如果已经存在,那么那个值会被替换,

    而键不会被替换。如果希望同时替换键和值,那么需要使用 g_hash_table_replace。它稍有不同,因此在下面同时展示了二者:

    #include <glib.h>
    #include
    <stdio.h>

    static char* texas_1, *texas_2;
    void key_destroyed(gpointer data) {
    printf(
    "Got a key destroy call for %s\n", data == texas_1 ? "texas_1" : "texas_2");
    }
    int main(int argc, char** argv) {
    GHashTable
    * hash = g_hash_table_new_full(g_str_hash, g_str_equal,
    (GDestroyNotify)key_destroyed, NULL);
    texas_1
    = g_strdup("Texas");
    texas_2
    = g_strdup("Texas");
    g_hash_table_insert(hash, texas_1,
    "Austin");
    printf(
    "Calling insert with the texas_2 key\n");
    g_hash_table_insert(hash, texas_2,
    "Houston");
    printf(
    "Calling replace with the texas_2 key\n");
    g_hash_table_replace(hash, texas_2,
    "Houston");
    printf(
    "Destroying hash, so goodbye texas_2\n");
    g_hash_table_destroy(hash);
    g_free(texas_1);
    g_free(texas_2);
    return 0;
    }

    ***** Output *****

    Calling insert with the texas_2 key
    Got a key destroy call for texas_2
    Calling replace with the texas_2 key
    Got a key destroy call for texas_1
    Destroying hash, so goodbye texas_2
    Got a key destroy call for texas_2

    3

    遍历 键/值 对

    有时需要遍历所有的 键/值 对。这里是如何使用 g_hash_table_foreach 来完成那项任务:

    #include <glib.h>
    #include
    <stdio.h>

    void iterator(gpointer key, gpointer value, gpointer user_data) {
    printf(user_data,
    *(gint*)key, value);
    }
    int main(int argc, char** argv) {
    GHashTable
    * hash = g_hash_table_new(g_int_hash, g_int_equal);
    gint
    * k_one = g_new(gint, 1), *k_two = g_new(gint, 1), *k_three = g_new(gint, 1);
    *k_one = 1, *k_two=2, *k_three = 3;
    g_hash_table_insert(hash, k_one,
    "one");
    g_hash_table_insert(hash, k_two,
    "four");
    g_hash_table_insert(hash, k_three,
    "nine");
    g_hash_table_foreach(hash, (GHFunc)iterator,
    "The square of %d is %s\n");
    g_hash_table_destroy(hash);
    return 0;
    }

    ***** Output *****

    The square of 1 is one
    The square of 2 is four
    The square of 3 is nine
    4

    查找条目

    使用 g_hash_table_find 函数来查找某个特定的值。这个函数支持查看每一个 键/值 对,直到定位到期望的值。这里是一个示例:

    #include <glib.h>
    #include
    <stdio.h>

    void value_destroyed(gpointer data) {
    printf(
    "Got a value destroy call for %d\n", GPOINTER_TO_INT(data));
    }
    gboolean finder(gpointer key, gpointer value, gpointer user_data) {
    return (GPOINTER_TO_INT(key) + GPOINTER_TO_INT(value)) == 42;
    }
    int main(int argc, char** argv) {
    GHashTable
    * hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
    NULL,
    (GDestroyNotify)value_destroyed);
    g_hash_table_insert(hash, GINT_TO_POINTER(
    6), GINT_TO_POINTER(36));
    g_hash_table_insert(hash, GINT_TO_POINTER(
    10), GINT_TO_POINTER(12));
    g_hash_table_insert(hash, GINT_TO_POINTER(
    20), GINT_TO_POINTER(22));
    gpointer item_ptr
    = g_hash_table_find(hash, (GHRFunc)finder, NULL);
    gint item
    = GPOINTER_TO_INT(item_ptr);
    printf(
    "%d + %d == 42\n", item, 42-item);
    g_hash_table_destroy(hash);
    return 0;
    }

    ***** Output *****

    36 + 6 == 42
    Got a value destroy call for 36
    Got a value destroy call for 22
    Got a value destroy call for 12

    5

    难处理的情形:从表中删除

    偶尔可能需要从一个 GHashTable 中删除某个条目,但却没有获得 GHashTable 所提供的任意 GDestroyNotify 函数的回调。

    要完成此任务,或者可以根据具体的键使用 g_hash_table_steal,或者根据所有匹配某个条件的键使用 g_hash_table_foreach_steal。

    #include <glib.h>
    #include
    <stdio.h>

    gboolean wide_open(gpointer key, gpointer value, gpointer user_data) {
    return TRUE;
    }
    void key_destroyed(gpointer data) {
    printf(
    "Got a GDestroyNotify callback\n");
    }
    int main(int argc, char** argv) {
    GHashTable
    * hash = g_hash_table_new_full(g_str_hash, g_str_equal,
    (GDestroyNotify)key_destroyed,
    (GDestroyNotify)key_destroyed);
    g_hash_table_insert(hash,
    "Texas", "Austin");
    g_hash_table_insert(hash,
    "Virginia", "Richmond");
    g_hash_table_insert(hash,
    "Ohio", "Columbus");
    g_hash_table_insert(hash,
    "Oregon", "Salem");
    g_hash_table_insert(hash,
    "New York", "Albany");
    printf(
    "Removing New York, you should see two callbacks\n");
    g_hash_table_remove(hash,
    "New York");
    if (g_hash_table_steal(hash, "Texas")) {
    printf(
    "Texas has been stolen, %d items remaining\n", g_hash_table_size(hash));
    }
    printf(
    "Stealing remaining items\n");
    g_hash_table_foreach_steal(hash, (GHRFunc)wide_open, NULL);
    printf(
    "Destroying the GHashTable, but it's empty, so no callbacks\n");
    g_hash_table_destroy(hash);
    return 0;
    }

    ***** Output *****

    Removing New York, you should see two callbacks
    Got a GDestroyNotify callback
    Got a GDestroyNotify callback
    Texas has been stolen, 3 items remaining
    Stealing remaining items
    Destroying the GHashTable, but it's empty, so no callbacks

    6

    高级查找:找到键和值

    针对需要从表中同时获得键和值的情况,GHashTable 提供了一个 g_hash_table_lookup_extended 函数。

    它与 g_hash_table_lookup 非常类似,但要接受更多两个参数。这些都是“out”参数;也就是说,它们是双重间接指针,当数据被定位时将指向它

    。这里是它的工作方式:

    #include <glib.h>
    #include
    <stdio.h>

    int main(int argc, char** argv) {
    GHashTable
    * hash = g_hash_table_new(g_str_hash, g_str_equal);
    g_hash_table_insert(hash,
    "Texas", "Austin");
    g_hash_table_insert(hash,
    "Virginia", "Richmond");
    g_hash_table_insert(hash,
    "Ohio", "Columbus");
    char* state = NULL;
    char* capital = NULL;
    char** key_ptr = &state;
    char** value_ptr = &capital;
    gboolean result
    = g_hash_table_lookup_extended(hash, "Ohio", (gpointer*)key_ptr, (gpointer*)value_ptr);
    if (result) {
    printf(
    "Found that the capital of %s is %s\n", capital, state);
    }
    if (!g_hash_table_lookup_extended(hash, "Vermont", (gpointer*)key_ptr, (gpointer*)value_ptr)) {
    printf(
    "Couldn't find Vermont in the hash table\n");
    }
    g_hash_table_destroy(hash);
    return 0;
    }

    ***** Output *****

    Found that the capital of Columbus is Ohio
    Couldn't find Vermont in the hash table

    7

    每个键多个值   有错误需要调试

    到目前为止已经介绍了每个键只拥有一个值的散列。不过有时您需要让一个键持有多个值。当出现这种需求时,

    使用 GSList 作为值并及 GSList 添加新的值通常是一个好的解决方案。不过,这需要稍多一些工作,如本例中所示:

    #include <glib.h>
    #include
    <stdio.h>

    void print(gpointer key, gpointer value, gpointer data) {
    printf(
    "Here are some cities in %s: ", key);
    g_slist_foreach((GSList
    *)value, (GFunc)printf, NULL);
    printf(
    "\n");
    }
    void destroy(gpointer key, gpointer value, gpointer data) {
    printf(
    "Freeing a GSList, first item is %s\n", ((GSList*)value)->data);
    g_slist_free(value);
    }
    int main(int argc, char** argv) {
    GHashTable
    * hash = g_hash_table_new(g_str_hash, g_str_equal);
    g_hash_table_insert(hash,
    "Texas",
    g_slist_append(g_hash_table_lookup(hash,
    "Texas"), "Austin "));
    g_hash_table_insert(hash,
    "Texas",
    g_slist_append(g_hash_table_lookup(hash,
    "Texas"), "Houston "));
    g_hash_table_insert(hash,
    "Virginia",
    g_slist_append(g_hash_table_lookup(hash,
    "Virginia"), "Richmond "));
    g_hash_table_insert(hash,
    "Virginia",
    g_slist_append(g_hash_table_lookup(hash,
    "Virginia"), "Keysville "));
    g_hash_table_foreach(hash, print, NULL);
    g_hash_table_foreach(hash, destroy, NULL);
    g_hash_table_destroy(hash);
    return 0;
    }

    ***** Output *****

    Here are some cities in Texas: Austin Houston
    Here are some cities in Virginia: Richmond Keysville
    Freeing a GSList, first item is Austin
    Freeing a GSList, first item is Richmond

  • 相关阅读:
    ElasticSearch第三步-中文分词
    centos 6.7 搭建tornado + nginx + supervisor的方法(已经实践)
    python ConfigParser 模块
    collections 模块(namedtuple, deque, Counter )
    Kali 开机报错解决方案
    debian 或者kali 安装git
    kali python pip3 的安装和卸载
    Kali 使用ssh,安装vmware tools 和字体重叠
    装饰器
    python2.7 报错(UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128))
  • 原文地址:https://www.cnblogs.com/wangkangluo1/p/2101983.html
Copyright © 2020-2023  润新知