構造体{ChainNodeのtypedef
構造体*次ChainNode;
CHAR *データ; //ファイルパス+ファイル名
} ChainNode。
typedefは構造体チェーン{
構造体ChainNode *ヘッド。
int型のカウント;
}鎖;
MAX_CONTEXT_LEN 50の#define
typedefは構造体のハッシュ{
チャーキー[MAX_CONTEXT_LEN + 2]。
チェーンチェーン。
UT_hash_handle HH;
}ハッシュ;
ハッシュ* strHash = NULL;
ボイドAddChainNode(CHAR *データ、チェーン*鎖)
{
ChainNode *ノード=(ChainNode *)はmalloc(はsizeof(ChainNode))。
ノード- >次= 0。
ノード- >データ=(CHAR *)はmalloc(はsizeof(CHAR)*(STRLEN(データ)+ 1))。
strcpyの(ノード- >データ、データ)。
鎖- >数++;
IF(鎖- >ヘッド== 0){
鎖- >ヘッド=ノード。
} {他
ノード- >次=鎖- >ヘッド。
鎖- >ヘッド=ノード。
}
を返します。
}
ボイドAddHashNode(CHAR *キー、CHAR *データ)
{
ハッシュ* hashNode。
HASH_FIND_STR(strHash、キー、hashNode)。
IF(hashNode == 0){
hashNode =(ハッシュ*)のmalloc(はsizeof(ハッシュ))。
strcpyの(hashNode->キー、キー)。
hashNode-> chain.count = 0;
hashNode-> chain.head = 0;
AddChainNode(データ、&hashNode->鎖);
HASH_ADD_STR(strHash、キー、hashNode)。
}他{
AddChainNode(データ、&hashNode->鎖);
}
を返します。
}
/ **
*サイズ* returnSizeの配列の配列を返します。
*アレイのサイズは* returnColumnSizesアレイとして返されます。
*注:どちらも返される配列と* columnSizes配列をmallocされなければならない、無料の発信者の通話を想定()。
* /
の#define MAX_PATH_LENGTH 10000
の#define MAX_CONTEXT_LEN 50
INT GETPATH(CHAR *パスチャー* pathBuffer)
{
int型のPOS。
{(; POS <STRLEN(パス)POS ++ POS = 0)のための
IF(パス[POS] == '「){
ブレーク。
}
pathBuffer [POS] =パス[POS]。
}
pathBuffer [POS ++] = '/'。
POSを返します。
}
fileprocボイド(INT pathLenを少なくとも、pathBufferチャー*、CHAR *パスの)
{
; INT = pathLenを少なくともCOUNTの
チャーコンテキスト[MAX_CONTEXT_LEN + 2];
//ルート/ A 1.TXT(ABCD)2.txt(EFGH)
// pathBuffer [COUNT ++ ] = '/';
のための(少なくともINT I = pathLenをする; I <strlenを(パス); I ++){
IF(パス[I] == '('){
pathBuffer [COUNT ++] = 0; //パス+ファイル名
INT = 0 contextLen;
一方(パス[I ++] =! '')){
コンテキスト[contextLen ++] =パス[I];
}
コンテキスト[contextLen ++] = 0; //ファイルの内容
//ファイルの内容は、挿入されたハッシュを除去されています
AddHashNode(コンテキスト、pathBuffer);
挿入が完了し//後、パスのみを含むようにバックオフ・カウントが空間濾過、この場合i)のまま
I ++;
カウント= pathLenを。
継続する;
}他{
pathBufferは=パス[I] [++カウント]。
}
}
}
ボイドDestroyHashNode(ハッシュ・ノード)
{
チェーンチェーン=ノード- >チェーン。
ChainNode *ヘッド、* TEMP。
ヘッド= chain.head。
一方、(ヘッド){
TEMP =頭部>次。
無料(頭部>データ);
無料(ヘッド);
ヘッド=温度;
}
フリー(ノード)。
リターン;
}
CHAR ***出力(INT * retuenSize、int型** returnColSize)
{
int型のカウント= 0;
ハッシュ* CURRENT_USER、* TMP;
HASH_ITER(HH、strHash、CURRENT_USER、TMP){
IF(current_user-> chain.count> 1){
++数えます。
}他{
HASH_DEL(strHash、CURRENT_USER)。/ *削除します。次の* /へのユーザの進歩
DestroyHashNode(CURRENT_USER)。/ *オプション-あなたが解放したい場合* /
}
}
* retuenSize =数えます。
文字***出力=(文字***)はmalloc(はsizeof(文字**)*数)。
int型* retCol =(int型*)はmalloc(はsizeof(int型)*数)。
* returnColSize = retCol。
カウント= 0;
ChainNode *ヘッド。
HASH_ITER(HH、strHash、CURRENT_USER、TMP){
IF(current_user-> chain.count> 1){
出力[カウント] =(CHAR **)はmalloc(はsizeof(文字*)*(current_user-> chain.count)) ;
ヘッド= current_user-> chain.head。
int型FILENUM = 0;
(ヘッド){ながら
出力[カウント] [FILENUM] =(CHAR *)はmalloc(はsizeof(CHAR)*(STRLEN(頭部>データ)+ 1))。
strcpyの(出力[カウント] [FILENUM]、頭部>データ)。
FILENUM ++;
ヘッド=頭部>次。
}
retCol [カウント] = current_user-> chain.count。
++数えます。
HASH_DEL(strHash、CURRENT_USER)。
DestroyHashNode(CURRENT_USER)。
}
}
strHash = NULL;
出力を返します。
}
チャー*** findDuplicate(チャー**パス、INT pathsSize、INT * returnSize、INT ** returnColumnSizes){
チャーpathBuffer [MAX_PATH_LENGTH]。
int型pathLenを;
int型pathLoop;
//好都合入力のそれぞれの行、経路を取っファイルパス
のために(pathLoop = 0; pathLoop <pathsSize; pathLoop ++){
//ルート/ A 1.TXT(ABCD)2.txt(EFGH)
pathLenを少なくともGETPATH =(パス[pathLoop]の、 pathBuffer); //レコードのファイルパスの長さ、0がCOUNTに格納されている- 1。
fileproc少なくともの(pathLenを、pathBuffer、パス[pathLoop]);
}
// 1つの上の送信データのハッシュ数のすべてのノードをトラバース
リターン出力(returnSize、returnColumnSizes);
}
https://blog.csdn.net/qq_23091073/article/details/86485095
使用uthashの
初期化
uthashは、UT_hash_handle HH含む構造独自のデータ構造を定義するためにユーザに要求する
値としても(オプション)キーと値を定義する必要があり、キーとしてID、名前を
構造体my_struct {
int型のID; / * *キー/
名char [10];
UT_hash_handle HH; / * * /このハッシュ可能構造を作り
};
typedefは構造体my_struct HashNode;
typedefは構造体my_struct * HashHead。
。1
2
3
4
5
6
7
8
追加
ハッシュテーブルデータに追加された
キーは、HASH_ADD_INTを使用することができるintで
使用HASH_ADD_STRのであってもよく、キーは文字列で
使用HASH_ADD_PTRであってもよいし、キーがポインターであり
、すべての実際のコールこの方法の上方、HASH_ADDを使用することができる、他のしかし、パラメータの簡素化
、ボイドhashTabel_add(HashHead *ヘッド、* HashNodeユーザー){
//述べたID上記のキー属性名は、しかし、非常に奇妙である、実際にマクロのパラメータとして置き換えられます
//あなたは、以下のソースコードを見ることができますが、intfieldは&に置き換え置き換えます((ADD) - >フィールド名)
IF(find_user(ヘッド*、USERS-> ID)!)
HASH_ADD_INT(ヘッド*、ID、ユーザ);
}
1
2
3。
4。
5。
6。
の#define HASH_ADD_INT(ヘッド、intfield、ADD)\
HASH_ADD(HH、頭、intfield、はsizeof(int型)、ADD)
の#define HASH_ADD(HH、頭、フィールド名、keylen_in、追加)\
HASH_ADD_KEYPTR(HH、頭、&((追加) - >フィールド名)、keylen_in、追加)
。1
2
。3
。4
代わりに
それを追加して、新しいノードを追加するために、同一のノード鍵を削除、添加前になり
使用HASH_REPLACE_INTであってもよいし、キーがintである場合に
ボイドreplace_user(HashHead *ヘッド、HashNode * newNode){
HashNode * oldNodeが= find_user (*ヘッド、newnode-> ID);
IF(oldNodeが)
HASH_REPLACE_INT(ヘッド*、ID、newNode、oldNodeが);
}
。1
2
。3
。4
。5
ルックアップ
キーに従ってノードを見つけるために
キーがintである場合、HASH_FIND_INTを使用することができます
HashNode * find_user(HashHeadヘッド、INT USER_ID){
HashNode * S。
HASH_FIND_INT(頭、&USER_ID、S)。/ * sの:出力ポインタ* /
リターン秒;
}
1
2
3
4
5
删除
删除节点
使用HASH_DEL
空隙DELETE_USER(HashHead *ヘッド、HashNode *ユーザ){
IF(ユーザ){
HASH_DEL(*ヘッド、ユーザ)。/ *ユーザー:deleteeへのポインタ* /
無料(利用者)。/ *オプション。それはあなた次第です!* /
}
}
1
2
3
4
5
6
计数
统计节点数
使用HASH_COUNT
INT count_user(HashHeadヘッド){
リターンHASH_COUNT(ヘッド);
}
1
2
3
遍历
遍历节点
可以用循环或者使用HASH_ITER
空隙print_user(HashHeadヘッド){
HashNode * S。
printf( "サイズは%D \ nは"、count_user(ヘッド))。
用(S =ヘッド; S!= NULL; S = S-> hh.next){
のprintf( "ユーザIDは%d、名前%S \ n"は、S-> ID、S->名);
}
}
ボイドprint_user_iterator(HashHeadヘッド){
HashNode * S * TMP。
printf( "サイズは%D \ nは"、count_user(ヘッド))。
HASH_ITER(HH、ヘッド、S、TMP){
のprintf( "ユーザID%のD:名前%S \ n"は、S-> ID、S->名);
/ * ...
2
。3
。4
。5
。6
。7
8
9
10
11
12は
13である
14
15
ソート
キーまたは値ができ、ソートノードに
HASH_SORT使用
int型name_sort(HashNode * A * B HashNode){
リターンのstrcmp(A->名、B->名前を);
}
INT id_sort(HashNode *、HashNode * B){
リターン(A-> ID - B-> ID)。
}
ボイドsort_by_name(HashHead *ヘッド){
HASH_SORT(*ヘッド、name_sort)。
}
ボイドsort_by_id(HashHead *ヘッド){
HASH_SORT(*ヘッド、id_sort)。
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
三、完整代码
の#include <stdio.hに>
する#include <STDLIB.H>
の#include "uthash.h"
typedefは構造体my_struct {
int型のID。/ *我々はキー* /としてこのフィールドを使用します
文字名[10]。
UT_hash_handle HH; / *この構造ハッシュ可能* /なり
} HashNode。
HashNode * HashHeadのtypedef。
int型count_user(HashHeadヘッド);
HashNode * find_user(HashHeadヘッド、INT USER_ID){
HashNode * S。
HASH_FIND_INT(頭、&USER_ID、S)。/ * sの:出力ポインタ* /
リターン秒;
}
ボイドADD_USER(HashHead *ヘッド、HashNode *ユーザ){
IF(find_user(*ヘッド、users-> ID)!)
HASH_ADD_INT(*ヘッド、ID、ユーザ);
}
ボイドreplace_user(HashHead *ヘッド、HashNode * newNode){
* oldNodeが= find_user HashNode(*ヘッド、newNode-> ID)。
(oldNodeが)場合
HASH_REPLACE_INT(*ヘッド、ID、newNode、oldNodeが)。
}
ボイドDELETE_USER(HashHead *ヘッド、HashNode *ユーザ){
IF(ユーザ){
HASH_DEL(*ヘッド、ユーザ)。/ *ユーザー:deleteeへのポインタ* /
無料(利用者)。/ *オプション。それはあなた次第です!* /
}
}
ボイドprint_user(HashHeadヘッド){
HashNode * S。
printf( "サイズは%D \ nは"、count_user(ヘッド))。
用(S =ヘッド; S!= NULL; S = S-> hh.next){
のprintf( "ユーザIDは%d、名前%S \ n"は、S-> ID、S->名);
}
}
ボイドprint_user_iterator(HashHeadヘッド){
HashNode * S * TMP。
printf( "サイズは%D \ nは"、count_user(ヘッド))。
HASH_ITER(HH、ヘッド、S、TMP){
のprintf( "ユーザID%のD:名前%S \ n"は、S-> ID、S->名);
/ * ... * /ここでSを削除し、自由にしても安全である
}
}
{int型のcount_user(HashHeadヘッド)
リターンHASH_COUNT(ヘッド);
}
int型name_sort(HashNode *、HashNode * B){
リターンのstrcmp(A->名、B->名);
}
INT id_sort(HashNode *、HashNode * B){
リターン(A-> ID - B-> ID)。
}
ボイドsort_by_name(HashHead *ヘッド){
HASH_SORT(*ヘッド、name_sort)。
}
ボイドsort_by_id(HashHead *ヘッド){
HASH_SORT(*ヘッド、id_sort)。
}
int型のmain()
{
のprintf( "-------------- INIT --------------- \ n");
HashHeadヘッド= NULL;
printf( "-------------- ---------------追加\ N");
HashNode * =ノードのmalloc(はsizeof(HashNode))。
ノード- > ID = 1。
strcpyの(ノード- >名前、 "トム");
ADD_USER(&ヘッド、ノード)。
ノード= malloc関数(はsizeof(HashNode))。
ノード- > ID = 2。
strcpyの(ノード- >名前、 "ジェリー");
ADD_USER(&ヘッド、ノード)。
ノード= malloc関数(はsizeof(HashNode))。
ノード- > ID = 3。
strcpyの(ノード- >名前、 "ジャック");
ADD_USER(&ヘッド、ノード)。
ノード= malloc関数(はsizeof(HashNode))。
ノード- > ID = 0。
strcpyの(ノード- >名前、 "ゼロ");
ADD_USER(&ヘッド、ノード)。
print_user(ヘッド)
printf( "-------------- ---------------置き換える\ N");
HashNode * newNode = malloc関数(はsizeof(HashNode))。
newNode-> ID = 3。
strcpyの(newNode->名、 "バラ");
replace_user(&ヘッド、newNode);
print_user(ヘッド)
printf( "削除--------------- -------------- \ N-");
DELETE_USER(&ヘッド、find_user(ヘッド,. 1));
print_user(ヘッド);
のprintf( "ID --------------- \ N- ---------------ソート・バイ");
sort_by_id(ヘッド& );
print_user(ヘッド);
のprintf( "ソート・バイ・名-------------- --------------- \ N-");
sort_by_name (&ヘッド);
print_user(ヘッド);
戻り0;
}
----------------
免責事項:この記事はBY-SA CC 4.0に従う、CSDNブロガー「aabond「オリジナル記事です著作権の契約は、再現し、元のソースのリンクと、この文を添付してください。
オリジナルリンクします。https://blog.csdn.net/qq_23091073/article/details/86485095