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

    原文作者:wangkangluo1
    原文地址: https://www.cnblogs.com/wangkangluo1/archive/2011/07/09/2101983.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞