├── .gitignore ├── c_struct ├── ArrayList-master.zip ├── README ├── arraylist.c ├── arraylist.h ├── c_hashmap-master.zip ├── datastructs-c-master.zip ├── hashmap-master.zip ├── hashmap.c ├── hashmap.h ├── hashmap_main.c ├── iamscottmoyers_hashmap.zip ├── stack-master.zip ├── stack.c ├── stack.h ├── stack_main.c ├── vector-master.zip ├── vector.c ├── vector.h ├── vector_main.c ├── vector_matteckert.c ├── vector_matteckert.h ├── vector_matteckert.zip └── vector_matteckert_main.c ├── cbigint ├── .gitignore ├── BigInt.c ├── BigInt.h ├── BigInt_test.c ├── README.md ├── demo.c ├── makefile └── test.c ├── cppbigint ├── CBigInt.cpp ├── CBigInt.h ├── CBigIntFib.cpp ├── CBigIntTest.cpp ├── CStrUtil.cpp ├── CStrUtil.h ├── CStrUtilTest.cpp └── CThrow.h ├── cpptool.cpp ├── cpptool.h ├── cpptool_main.cpp ├── ctool.c ├── ctool.h ├── ctool_main.c ├── c语言动态内存分配.c ├── debug.c ├── debug.h ├── dynamic_array.c ├── dynamic_array.cpp ├── dynamic_array2.cpp ├── dynamic_array3.cpp ├── log.c ├── log.h ├── myBigInt ├── CBigInt.cpp ├── CBigInt.h └── main.cpp ├── simpletest.h ├── simpletest_main.c ├── sort_坑.cpp ├── string_buffer.c ├── string_buffer.h ├── stringx ├── stringx.c └── stringx.h ├── test.c ├── 位运算.cpp ├── 动态字符串链接.cpp ├── 字符串替换.c ├── 工具包 └── copyfile.zip ├── 开房数据查询.cpp └── 进制转换.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.vcxproj 3 | *.filters 4 | /Debug/ 5 | /Release/ 6 | 7 | -------------------------------------------------------------------------------- /c_struct/ArrayList-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/c_struct/ArrayList-master.zip -------------------------------------------------------------------------------- /c_struct/README: -------------------------------------------------------------------------------- 1 | This is a simple C hashmap, using strings for the keys. 2 | 3 | Originally based on code by Eliot Back at http://elliottback.com/wp/hashmap-implementation-in-c/ 4 | Reworked by Pete Warden - http://petewarden.typepad.com/searchbrowser/2010/01/c-hashmap.html 5 | 6 | main.c contains an example that tests the functionality of the hashmap module. 7 | To compile it, run something like this on your system: 8 | gcc main.c hashmap.c -o hashmaptest 9 | 10 | There are no restrictions on how you reuse this code. -------------------------------------------------------------------------------- /c_struct/arraylist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $ 3 | * 4 | * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. 5 | * Michael Clark 6 | * 7 | * This library is free software; you can redistribute it and/or modify 8 | * it under the terms of the MIT license. See COPYING for details. 9 | * 10 | */ 11 | 12 | 13 | #include 14 | # include 15 | # include 16 | 17 | #if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD) 18 | # include 19 | #endif /* HAVE_STRINGS_H */ 20 | 21 | #include "arraylist.h" 22 | 23 | struct array_list* 24 | array_list_new(array_list_free_fn *free_fn) 25 | { 26 | struct array_list *arr; 27 | 28 | arr = (struct array_list*)calloc(1, sizeof(struct array_list)); 29 | if(!arr) return NULL; 30 | arr->size = ARRAY_LIST_DEFAULT_SIZE; 31 | arr->length = 0; 32 | arr->free_fn = free_fn; 33 | if(!(arr->array = (void**)calloc(sizeof(void*), arr->size))) { 34 | free(arr); 35 | return NULL; 36 | } 37 | return arr; 38 | } 39 | 40 | extern void 41 | array_list_free(struct array_list *arr) 42 | { 43 | int i; 44 | for(i = 0; i < arr->length; i++) 45 | if(arr->array[i]) arr->free_fn(arr->array[i]); 46 | free(arr->array); 47 | free(arr); 48 | } 49 | 50 | void* 51 | array_list_get_idx(struct array_list *arr, int i) 52 | { 53 | if(i >= arr->length) return NULL; 54 | return arr->array[i]; 55 | } 56 | 57 | static int array_list_expand_internal(struct array_list *arr, int max) 58 | { 59 | void *t; 60 | int new_size; 61 | 62 | if(max < arr->size) return 0; 63 | /* Avoid undefined behaviour on int32 overflow */ 64 | if( arr->size >= INT_MAX / 2 ) 65 | new_size = max; 66 | else 67 | { 68 | new_size = arr->size << 1; 69 | if (new_size < max) 70 | new_size = max; 71 | } 72 | if((size_t)new_size > (~((size_t)0)) / sizeof(void*)) return -1; 73 | if(!(t = realloc(arr->array, ((size_t)new_size)*sizeof(void*)))) return -1; 74 | arr->array = (void**)t; 75 | (void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*)); 76 | arr->size = new_size; 77 | return 0; 78 | } 79 | 80 | int 81 | array_list_put_idx(struct array_list *arr, int idx, void *data) 82 | { 83 | if( idx < 0 || idx > INT_MAX - 1 ) return -1; 84 | if(array_list_expand_internal(arr, idx+1)) return -1; 85 | if(arr->array[idx]) arr->free_fn(arr->array[idx]); 86 | arr->array[idx] = data; 87 | if(arr->length <= idx) arr->length = idx + 1; 88 | return 0; 89 | } 90 | 91 | int 92 | array_list_add(struct array_list *arr, void *data) 93 | { 94 | return array_list_put_idx(arr, arr->length, data); 95 | } 96 | 97 | void 98 | array_list_sort(struct array_list *arr, int(*sort_fn)(const void *, const void *)) 99 | { 100 | qsort(arr->array, arr->length, sizeof(arr->array[0]), sort_fn); 101 | } 102 | 103 | void* array_list_bsearch(const void **key, struct array_list *arr, 104 | int (*sort_fn)(const void *, const void *)) 105 | { 106 | return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]), 107 | sort_fn); 108 | } 109 | 110 | int 111 | array_list_length(struct array_list *arr) 112 | { 113 | return arr->length; 114 | } 115 | 116 | int 117 | array_list_del_idx( struct array_list *arr, int idx, int count ) 118 | { 119 | int i, stop; 120 | 121 | stop = idx + count; 122 | if ( idx >= arr->length || stop > arr->length ) return -1; 123 | for ( i = idx; i < stop; ++i ) { 124 | if ( arr->array[i] ) arr->free_fn( arr->array[i] ); 125 | } 126 | memmove( arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void*) ); 127 | arr->length -= count; 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /c_struct/arraylist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $ 3 | * 4 | * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. 5 | * Michael Clark 6 | * 7 | * This library is free software; you can redistribute it and/or modify 8 | * it under the terms of the MIT license. See COPYING for details. 9 | * 10 | */ 11 | 12 | #ifndef _arraylist_h_ 13 | #define _arraylist_h_ 14 | 15 | //https://github.com/json-c/json-c 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #define ARRAY_LIST_DEFAULT_SIZE 32 21 | 22 | typedef void (array_list_free_fn) (void *data); 23 | 24 | struct array_list 25 | { 26 | void **array; 27 | int length; 28 | int size; 29 | array_list_free_fn *free_fn; 30 | }; 31 | 32 | extern struct array_list* 33 | array_list_new(array_list_free_fn *free_fn); 34 | 35 | extern void 36 | array_list_free(struct array_list *al); 37 | 38 | extern void* 39 | array_list_get_idx(struct array_list *al, int i); 40 | 41 | extern int 42 | array_list_put_idx(struct array_list *al, int i, void *data); 43 | 44 | extern int 45 | array_list_add(struct array_list *al, void *data); 46 | 47 | extern int 48 | array_list_length(struct array_list *al); 49 | 50 | extern void 51 | array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *)); 52 | 53 | extern void* array_list_bsearch(const void **key, 54 | struct array_list *arr, 55 | int (*sort_fn)(const void *, const void *)); 56 | 57 | extern int 58 | array_list_del_idx(struct array_list *arr, int i, int count); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /c_struct/c_hashmap-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/c_struct/c_hashmap-master.zip -------------------------------------------------------------------------------- /c_struct/datastructs-c-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/c_struct/datastructs-c-master.zip -------------------------------------------------------------------------------- /c_struct/hashmap-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/c_struct/hashmap-master.zip -------------------------------------------------------------------------------- /c_struct/hashmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic map implementation. 3 | */ 4 | #include "hashmap.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define INITIAL_SIZE (256) 11 | #define MAX_CHAIN_LENGTH (8) 12 | 13 | /* We need to keep keys and values */ 14 | typedef struct _hashmap_element{ 15 | char* key; 16 | int in_use; 17 | any_t data; 18 | } hashmap_element; 19 | 20 | /* A hashmap has some maximum size and current size, 21 | * as well as the data to hold. */ 22 | typedef struct _hashmap_map{ 23 | int table_size; 24 | int size; 25 | hashmap_element *data; 26 | } hashmap_map; 27 | 28 | /* 29 | * Return an empty hashmap, or NULL on failure. 30 | */ 31 | map_t hashmap_new() { 32 | hashmap_map* m = (hashmap_map*) malloc(sizeof(hashmap_map)); 33 | if(!m) goto err; 34 | 35 | m->data = (hashmap_element*) calloc(INITIAL_SIZE, sizeof(hashmap_element)); 36 | if(!m->data) goto err; 37 | 38 | m->table_size = INITIAL_SIZE; 39 | m->size = 0; 40 | 41 | return m; 42 | err: 43 | if (m) 44 | hashmap_free(m); 45 | return NULL; 46 | } 47 | 48 | /* The implementation here was originally done by Gary S. Brown. I have 49 | borrowed the tables directly, and made some minor changes to the 50 | crc32-function (including changing the interface). //ylo */ 51 | 52 | /* ============================================================= */ 53 | /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ 54 | /* code or tables extracted from it, as desired without restriction. */ 55 | /* */ 56 | /* First, the polynomial itself and its table of feedback terms. The */ 57 | /* polynomial is */ 58 | /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ 59 | /* */ 60 | /* Note that we take it "backwards" and put the highest-order term in */ 61 | /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ 62 | /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ 63 | /* the MSB being 1. */ 64 | /* */ 65 | /* Note that the usual hardware shift register implementation, which */ 66 | /* is what we're using (we're merely optimizing it by doing eight-bit */ 67 | /* chunks at a time) shifts bits into the lowest-order term. In our */ 68 | /* implementation, that means shifting towards the right. Why do we */ 69 | /* do it this way? Because the calculated CRC must be transmitted in */ 70 | /* order from highest-order term to lowest-order term. UARTs transmit */ 71 | /* characters in order from LSB to MSB. By storing the CRC this way, */ 72 | /* we hand it to the UART in the order low-byte to high-byte; the UART */ 73 | /* sends each low-bit to hight-bit; and the result is transmission bit */ 74 | /* by bit from highest- to lowest-order term without requiring any bit */ 75 | /* shuffling on our part. Reception works similarly. */ 76 | /* */ 77 | /* The feedback terms table consists of 256, 32-bit entries. Notes: */ 78 | /* */ 79 | /* The table can be generated at runtime if desired; code to do so */ 80 | /* is shown later. It might not be obvious, but the feedback */ 81 | /* terms simply represent the results of eight shift/xor opera- */ 82 | /* tions for all combinations of data and CRC register values. */ 83 | /* */ 84 | /* The values must be right-shifted by eight bits by the "updcrc" */ 85 | /* logic; the shift must be unsigned (bring in zeroes). On some */ 86 | /* hardware you could probably optimize the shift in assembler by */ 87 | /* using byte-swap instructions. */ 88 | /* polynomial $edb88320 */ 89 | /* */ 90 | /* -------------------------------------------------------------------- */ 91 | 92 | static unsigned long crc32_tab[] = { 93 | 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 94 | 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 95 | 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 96 | 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 97 | 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 98 | 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 99 | 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 100 | 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 101 | 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 102 | 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 103 | 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 104 | 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 105 | 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 106 | 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 107 | 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 108 | 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 109 | 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 110 | 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 111 | 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 112 | 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 113 | 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 114 | 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 115 | 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 116 | 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 117 | 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 118 | 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 119 | 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 120 | 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 121 | 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 122 | 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 123 | 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 124 | 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 125 | 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 126 | 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 127 | 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 128 | 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 129 | 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 130 | 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 131 | 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 132 | 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 133 | 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 134 | 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 135 | 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 136 | 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 137 | 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 138 | 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 139 | 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 140 | 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 141 | 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 142 | 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 143 | 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 144 | 0x2d02ef8dL 145 | }; 146 | 147 | /* Return a 32-bit CRC of the contents of the buffer. */ 148 | 149 | unsigned long crc32(const unsigned char *s, unsigned int len) 150 | { 151 | unsigned int i; 152 | unsigned long crc32val; 153 | 154 | crc32val = 0; 155 | for (i = 0; i < len; i ++) 156 | { 157 | crc32val = 158 | crc32_tab[(crc32val ^ s[i]) & 0xff] ^ 159 | (crc32val >> 8); 160 | } 161 | return crc32val; 162 | } 163 | 164 | /* 165 | * Hashing function for a string 166 | */ 167 | unsigned int hashmap_hash_int(hashmap_map * m, char* keystring){ 168 | 169 | unsigned long key = crc32((unsigned char*)(keystring), strlen(keystring)); 170 | 171 | /* Robert Jenkins' 32 bit Mix Function */ 172 | key += (key << 12); 173 | key ^= (key >> 22); 174 | key += (key << 4); 175 | key ^= (key >> 9); 176 | key += (key << 10); 177 | key ^= (key >> 2); 178 | key += (key << 7); 179 | key ^= (key >> 12); 180 | 181 | /* Knuth's Multiplicative Method */ 182 | key = (key >> 3) * 2654435761; 183 | 184 | return key % m->table_size; 185 | } 186 | 187 | /* 188 | * Return the integer of the location in data 189 | * to store the point to the item, or MAP_FULL. 190 | */ 191 | int hashmap_hash(map_t in, char* key){ 192 | int curr; 193 | int i; 194 | 195 | /* Cast the hashmap */ 196 | hashmap_map* m = (hashmap_map *) in; 197 | 198 | /* If full, return immediately */ 199 | if(m->size >= (m->table_size/2)) return MAP_FULL; 200 | 201 | /* Find the best index */ 202 | curr = hashmap_hash_int(m, key); 203 | 204 | /* Linear probing */ 205 | for(i = 0; i< MAX_CHAIN_LENGTH; i++){ 206 | if(m->data[curr].in_use == 0) 207 | return curr; 208 | 209 | if(m->data[curr].in_use == 1 && (strcmp(m->data[curr].key,key)==0)) 210 | return curr; 211 | 212 | curr = (curr + 1) % m->table_size; 213 | } 214 | 215 | return MAP_FULL; 216 | } 217 | 218 | /* 219 | * Doubles the size of the hashmap, and rehashes all the elements 220 | */ 221 | int hashmap_rehash(map_t in){ 222 | int i; 223 | int old_size; 224 | hashmap_element* curr; 225 | 226 | /* Setup the new elements */ 227 | hashmap_map *m = (hashmap_map *) in; 228 | hashmap_element* temp = (hashmap_element *) 229 | calloc(2 * m->table_size, sizeof(hashmap_element)); 230 | if(!temp) return MAP_OMEM; 231 | 232 | /* Update the array */ 233 | curr = m->data; 234 | m->data = temp; 235 | 236 | /* Update the size */ 237 | old_size = m->table_size; 238 | m->table_size = 2 * m->table_size; 239 | m->size = 0; 240 | 241 | /* Rehash the elements */ 242 | for(i = 0; i < old_size; i++){ 243 | int status; 244 | 245 | if (curr[i].in_use == 0) 246 | continue; 247 | 248 | status = hashmap_put(m, curr[i].key, curr[i].data); 249 | if (status != MAP_OK) 250 | return status; 251 | } 252 | 253 | free(curr); 254 | 255 | return MAP_OK; 256 | } 257 | 258 | /* 259 | * Add a pointer to the hashmap with some key 260 | */ 261 | int hashmap_put(map_t in, char* key, any_t value){ 262 | int index; 263 | hashmap_map* m; 264 | 265 | /* Cast the hashmap */ 266 | m = (hashmap_map *) in; 267 | 268 | /* Find a place to put our value */ 269 | index = hashmap_hash(in, key); 270 | while(index == MAP_FULL){ 271 | if (hashmap_rehash(in) == MAP_OMEM) { 272 | return MAP_OMEM; 273 | } 274 | index = hashmap_hash(in, key); 275 | } 276 | 277 | /* Set the data */ 278 | m->data[index].data = value; 279 | m->data[index].key = key; 280 | m->data[index].in_use = 1; 281 | m->size++; 282 | 283 | return MAP_OK; 284 | } 285 | 286 | /* 287 | * Get your pointer out of the hashmap with a key 288 | */ 289 | int hashmap_get(map_t in, char* key, any_t *arg){ 290 | int curr; 291 | int i; 292 | hashmap_map* m; 293 | 294 | /* Cast the hashmap */ 295 | m = (hashmap_map *) in; 296 | 297 | /* Find data location */ 298 | curr = hashmap_hash_int(m, key); 299 | 300 | /* Linear probing, if necessary */ 301 | for(i = 0; idata[curr].in_use; 304 | if (in_use == 1){ 305 | if (strcmp(m->data[curr].key,key)==0){ 306 | *arg = (m->data[curr].data); 307 | return MAP_OK; 308 | } 309 | } 310 | 311 | curr = (curr + 1) % m->table_size; 312 | } 313 | 314 | *arg = NULL; 315 | 316 | /* Not found */ 317 | return MAP_MISSING; 318 | } 319 | 320 | /* 321 | * Iterate the function parameter over each element in the hashmap. The 322 | * additional any_t argument is passed to the function as its first 323 | * argument and the hashmap element is the second. 324 | */ 325 | int hashmap_iterate(map_t in, PFany f, any_t item) { 326 | int i; 327 | 328 | /* Cast the hashmap */ 329 | hashmap_map* m = (hashmap_map*) in; 330 | 331 | /* On empty hashmap, return immediately */ 332 | if (hashmap_length(m) <= 0) 333 | return MAP_MISSING; 334 | 335 | /* Linear probing */ 336 | for(i = 0; i< m->table_size; i++) 337 | if(m->data[i].in_use != 0) { 338 | any_t data = (any_t) (m->data[i].data); 339 | int status = f(item, data); 340 | if (status != MAP_OK) { 341 | return status; 342 | } 343 | } 344 | 345 | return MAP_OK; 346 | } 347 | 348 | /* 349 | * Remove an element with that key from the map 350 | */ 351 | int hashmap_remove(map_t in, char* key){ 352 | int i; 353 | int curr; 354 | hashmap_map* m; 355 | 356 | /* Cast the hashmap */ 357 | m = (hashmap_map *) in; 358 | 359 | /* Find key */ 360 | curr = hashmap_hash_int(m, key); 361 | 362 | /* Linear probing, if necessary */ 363 | for(i = 0; idata[curr].in_use; 366 | if (in_use == 1){ 367 | if (strcmp(m->data[curr].key,key)==0){ 368 | /* Blank out the fields */ 369 | m->data[curr].in_use = 0; 370 | m->data[curr].data = NULL; 371 | m->data[curr].key = NULL; 372 | 373 | /* Reduce the size */ 374 | m->size--; 375 | return MAP_OK; 376 | } 377 | } 378 | curr = (curr + 1) % m->table_size; 379 | } 380 | 381 | /* Data not found */ 382 | return MAP_MISSING; 383 | } 384 | 385 | /* Deallocate the hashmap */ 386 | void hashmap_free(map_t in){ 387 | hashmap_map* m = (hashmap_map*) in; 388 | free(m->data); 389 | free(m); 390 | } 391 | 392 | /* Return the length of the hashmap */ 393 | int hashmap_length(map_t in){ 394 | hashmap_map* m = (hashmap_map *) in; 395 | if(m != NULL) return m->size; 396 | else return 0; 397 | } -------------------------------------------------------------------------------- /c_struct/hashmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic hashmap manipulation functions 3 | * 4 | * Originally by Elliot C Back - http://elliottback.com/wp/hashmap-implementation-in-c/ 5 | * 6 | * Modified by Pete Warden to fix a serious performance problem, support strings as keys 7 | * and removed thread synchronization - http://petewarden.typepad.com 8 | */ 9 | #ifndef __HASHMAP_H__ 10 | #define __HASHMAP_H__ 11 | 12 | #define MAP_MISSING -3 /* No such element */ 13 | #define MAP_FULL -2 /* Hashmap is full */ 14 | #define MAP_OMEM -1 /* Out of Memory */ 15 | #define MAP_OK 0 /* OK */ 16 | 17 | /* 18 | * any_t is a pointer. This allows you to put arbitrary structures in 19 | * the hashmap. 20 | */ 21 | typedef void *any_t; 22 | 23 | /* 24 | * PFany is a pointer to a function that can take two any_t arguments 25 | * and return an integer. Returns status code.. 26 | */ 27 | typedef int (*PFany)(any_t, any_t); 28 | 29 | /* 30 | * map_t is a pointer to an internally maintained data structure. 31 | * Clients of this package do not need to know how hashmaps are 32 | * represented. They see and manipulate only map_t's. 33 | */ 34 | typedef any_t map_t; 35 | 36 | /* 37 | * Return an empty hashmap. Returns NULL if empty. 38 | */ 39 | extern map_t hashmap_new(); 40 | 41 | /* 42 | * Iteratively call f with argument (item, data) for 43 | * each element data in the hashmap. The function must 44 | * return a map status code. If it returns anything other 45 | * than MAP_OK the traversal is terminated. f must 46 | * not reenter any hashmap functions, or deadlock may arise. 47 | */ 48 | extern int hashmap_iterate(map_t in, PFany f, any_t item); 49 | 50 | /* 51 | * Add an element to the hashmap. Return MAP_OK or MAP_OMEM. 52 | */ 53 | extern int hashmap_put(map_t in, char* key, any_t value); 54 | 55 | /* 56 | * Get an element from the hashmap. Return MAP_OK or MAP_MISSING. 57 | */ 58 | extern int hashmap_get(map_t in, char* key, any_t *arg); 59 | 60 | /* 61 | * Remove an element from the hashmap. Return MAP_OK or MAP_MISSING. 62 | */ 63 | extern int hashmap_remove(map_t in, char* key); 64 | 65 | /* 66 | * Get any element. Return MAP_OK or MAP_MISSING. 67 | * remove - should the element be removed from the hashmap 68 | */ 69 | extern int hashmap_get_one(map_t in, any_t *arg, int remove); 70 | 71 | /* 72 | * Free the hashmap 73 | */ 74 | extern void hashmap_free(map_t in); 75 | 76 | /* 77 | * Get the current size of a hashmap 78 | */ 79 | extern int hashmap_length(map_t in); 80 | 81 | #endif __HASHMAP_H__ -------------------------------------------------------------------------------- /c_struct/hashmap_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A unit test and example of how to use the simple C hashmap 3 | */ 4 | 5 | #define _CRT_SECURE_NO_WARNINGS 1 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "hashmap.h" 13 | 14 | #define KEY_MAX_LENGTH (256) 15 | #define KEY_PREFIX ("somekey") 16 | #define KEY_COUNT (1024*1024) 17 | 18 | #if WIN32 19 | #define snprintf _snprintf 20 | 21 | #endif 22 | 23 | typedef struct data_struct_s 24 | { 25 | char key_string[KEY_MAX_LENGTH]; 26 | int number; 27 | } data_struct_t; 28 | 29 | int main(char* argv, int argc) 30 | { 31 | int index; 32 | int error; 33 | map_t mymap; 34 | char key_string[KEY_MAX_LENGTH]; 35 | data_struct_t* value; 36 | 37 | mymap = hashmap_new(); 38 | 39 | /* First, populate the hash map with ascending values */ 40 | for (index=0; indexkey_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index); 45 | value->number = index; 46 | 47 | error = hashmap_put(mymap, value->key_string, value); 48 | assert(error==MAP_OK); 49 | } 50 | 51 | /* Now, check all of the expected values are there */ 52 | for (index=0; indexnumber==index); 61 | } 62 | 63 | /* Make sure that a value that wasn't in the map can't be found */ 64 | snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, KEY_COUNT); 65 | 66 | error = hashmap_get(mymap, key_string, (void**)(&value)); 67 | 68 | /* Make sure the value was not found */ 69 | assert(error==MAP_MISSING); 70 | 71 | /* Free all of the values we allocated and remove them from the map */ 72 | for (index=0; index 4 | #include 5 | 6 | void stackInitialize(struct stack *stack, uint32_t elementSize) 7 | { 8 | stack->elements = NULL; 9 | stack->count = stack->capacity = 0; 10 | stack->elementSize = elementSize; 11 | } 12 | 13 | void stackFree(struct stack *stack) 14 | { 15 | free(stack->elements); 16 | } 17 | 18 | void *stackGet(struct stack *stack, uint32_t index) 19 | { 20 | return stack->elements + stack->elementSize * index; 21 | } 22 | 23 | void *stackPop(struct stack *stack) 24 | { 25 | if(stack->count > 0) { 26 | return stack->elements + --stack->count * stack->elementSize; 27 | } 28 | else { 29 | return NULL; 30 | } 31 | } 32 | 33 | void stackPush(struct stack *stack, void *data) 34 | { 35 | if(++stack->count > stack->capacity) { 36 | stack->capacity <<= 1; 37 | if(stack->capacity < stack->count) stack->capacity = stack->count; 38 | 39 | stack->elements = realloc(stack->elements, stack->elementSize * stack->capacity); 40 | } 41 | 42 | memcpy(stack->elements + stack->elementSize * (stack->count - 1), data, stack->elementSize); 43 | } 44 | 45 | void stackRemove(struct stack *stack, uint32_t index) 46 | { 47 | if(index != --stack->count) { 48 | memmove(stack->elements + index * stack->elementSize, stack->elements + (index + 1) * stack->elementSize, (stack->count - index) * stack->elementSize); 49 | } 50 | } 51 | 52 | void stackClear(struct stack *stack) 53 | { 54 | stack->count = 0; 55 | } 56 | 57 | uint32_t stackSize(struct stack *stack) 58 | { 59 | return stack->count; 60 | } 61 | 62 | int32_t stackIndexOf(struct stack *stack, void *element) 63 | { 64 | uint32_t i; 65 | 66 | for(i = 0; i < stack->count; ++i) { 67 | if(memcmp(element, stack->elements + stack->elementSize * i, stack->elementSize) == 0) return i; 68 | } 69 | 70 | return -1; 71 | } -------------------------------------------------------------------------------- /c_struct/stack.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct stack { 6 | uint8_t *elements; 7 | uint32_t count; 8 | uint32_t capacity; 9 | uint32_t elementSize; 10 | }; 11 | 12 | void stackInitialize(struct stack *stack, uint32_t elementSize); 13 | void stackFree(struct stack *stack); 14 | 15 | void *stackGet(struct stack *stack, uint32_t index); 16 | void *stackPop(struct stack *stack); 17 | void stackPush(struct stack *stack, void *data); 18 | void stackRemove(struct stack *stack, uint32_t index); 19 | void stackClear(struct stack *stack); 20 | uint32_t stackSize(struct stack *stack); 21 | int32_t stackIndexOf(struct stack *stack, void *element); 22 | -------------------------------------------------------------------------------- /c_struct/stack_main.c: -------------------------------------------------------------------------------- 1 | 2 | #define _CRT_SECURE_NO_WARNINGS 3 | 4 | #include "stack.h" 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | void test_Vector() 11 | { 12 | struct stack* alist = (struct stack*)malloc(sizeof(struct stack)); 13 | stackInitialize(alist,1024); 14 | 15 | int i = 0; 16 | for (i = 0; i < 15; i++) 17 | { 18 | 19 | char* tmp = (char*)malloc(sizeof(char)* 512); 20 | memset(tmp, 0, sizeof(char)* 512); 21 | sprintf(tmp, "hehe%d", i); 22 | printf("%s\n", tmp); 23 | stackPush(alist, tmp); 24 | } 25 | 26 | printf("\n\n"); 27 | 28 | int len = stackSize(alist); 29 | for (i = 0; i < len; i++) 30 | { 31 | char* tmp; 32 | //tmp=stackGet(alist, i); 33 | tmp=stackPop(alist); 34 | printf("%s\n", tmp); 35 | } 36 | 37 | stackFree(alist); 38 | 39 | 40 | 41 | } 42 | 43 | int main(int argc, char* argv[]) 44 | { 45 | 46 | test_Vector(); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /c_struct/vector-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/c_struct/vector-master.zip -------------------------------------------------------------------------------- /c_struct/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "vector.h" 6 | 7 | #ifndef VEC_INITCAP 8 | #define VEC_INITCAP (8) 9 | #endif 10 | 11 | inline static void _vector_shift_left(struct vector *vec, size_t index) 12 | { 13 | if (index < vec->count - 1) { 14 | for (size_t i = index; i < vec->count; ++i) { 15 | vec->mem[i] = vec->mem[1 + i]; 16 | } 17 | } 18 | 19 | --vec->count; 20 | } 21 | 22 | int vector_add(struct vector *vec, void *item) 23 | { 24 | int rc = VECE_OK; 25 | 26 | if (VECE_OK == (rc = vector_reserve(vec, vec->count + 1))) { 27 | vec->mem[vec->count++] = item; 28 | } 29 | 30 | return rc; 31 | } 32 | 33 | int vector_apply(struct vector *vec, void (*func)(void *)) 34 | { 35 | int rc = VECE_OK; 36 | void *item = NULL; 37 | 38 | if (vec && func) { 39 | for (size_t i = 0, j = vector_count(vec); i < j; ++i) { 40 | rc = vector_get(vec, i, &item); 41 | assert(VECE_OK == rc); 42 | func(item); 43 | } 44 | } else { 45 | rc = VECE_NULL_POINTER; 46 | } 47 | 48 | return rc; 49 | } 50 | 51 | int vector_delete(struct vector *vec, size_t index, void **item) 52 | { 53 | int rc = VECE_OUT_OF_BOUNDS; 54 | 55 | if (vec->count > index) { 56 | if (item) { 57 | *item = vec->mem[index]; 58 | } 59 | 60 | _vector_shift_left(vec, index); 61 | rc = VECE_OK; 62 | } 63 | 64 | return rc; 65 | } 66 | 67 | int vector_free(struct vector *vec) 68 | { 69 | int rc = VECE_NULL_POINTER; 70 | 71 | if (vec) { 72 | free(vec->mem); 73 | rc = vector_init(vec); 74 | } 75 | 76 | return rc; 77 | } 78 | 79 | int vector_get(struct vector *vec, size_t index, void **item) 80 | { 81 | if (!vec) { 82 | return VECE_NULL_POINTER; 83 | } 84 | 85 | if (vec->count > index) { 86 | *item = vec->mem[index]; 87 | return VECE_OK; 88 | } 89 | 90 | return VECE_OUT_OF_BOUNDS; 91 | } 92 | 93 | int vector_init(struct vector *vec) 94 | { 95 | int rc = VECE_NULL_POINTER; 96 | 97 | if (vec) { 98 | vec->count = 0; 99 | vec->max = 0; 100 | vec->mem = NULL; 101 | 102 | rc = VECE_OK; 103 | } 104 | 105 | return rc; 106 | } 107 | 108 | int vector_reserve(struct vector *vec, size_t size) 109 | { 110 | if (!vec) { 111 | return VECE_NULL_POINTER; 112 | } else if (size <= vec->max) { 113 | return VECE_OK; 114 | } else if (vec->max) { 115 | do { 116 | vec->max *= 2; 117 | } while (size > vec->max); 118 | } else { 119 | vec->max = VEC_INITCAP; 120 | } 121 | 122 | if (!(vec->mem = realloc(vec->mem, vec->max * sizeof(void *)))) { 123 | return ENOMEM == errno ? VECE_OUT_OF_MEMORY : VECE_OK; 124 | } 125 | 126 | return VECE_OK; 127 | } 128 | 129 | int vector_set(struct vector *vec, size_t index, void *item) 130 | { 131 | if (!vec) { 132 | return VECE_NULL_POINTER; 133 | } 134 | 135 | if (vec->count > index) { 136 | vec->mem[index] = item; 137 | return VECE_OK; 138 | } 139 | 140 | return VECE_OUT_OF_BOUNDS; 141 | } 142 | 143 | int vector_swap(struct vector *vec, size_t idx1, size_t idx2) 144 | { 145 | int rc = VECE_OK; 146 | void *item1 = NULL; 147 | void *item2 = NULL; 148 | 149 | if (VECE_OK != (rc = vector_get(vec, idx1, &item1))) { 150 | return rc; 151 | } 152 | 153 | if (VECE_OK != (rc = vector_get(vec, idx2, &item2))) { 154 | return rc; 155 | } 156 | 157 | rc = vector_set(vec, idx1, item2); 158 | assert(VECE_OK == rc); 159 | rc = vector_set(vec, idx2, item1); 160 | assert(VECE_OK == rc); 161 | 162 | return rc; 163 | } 164 | 165 | -------------------------------------------------------------------------------- /c_struct/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef __H_CEEF6E83FC3C441784ECEC6539B91AEB__ 2 | #define __H_CEEF6E83FC3C441784ECEC6539B91AEB__ 3 | 4 | #include 5 | #include 6 | 7 | enum { 8 | VECE_OK = 0, 9 | VECE_NULL_POINTER, 10 | VECE_OUT_OF_MEMORY, 11 | VECE_OUT_OF_BOUNDS 12 | }; 13 | 14 | struct vector { 15 | size_t count; 16 | size_t max; 17 | void **mem; 18 | }; 19 | 20 | 21 | #if defined(WIN32) && !defined(__cplusplus) 22 | #define inline __inline 23 | 24 | #endif 25 | 26 | 27 | 28 | inline static size_t vector_capacity(const struct vector *vec) 29 | { 30 | return vec ? vec->max : 0; 31 | } 32 | 33 | inline static size_t vector_count(const struct vector *vec) 34 | { 35 | return vec ? vec->count : 0; 36 | } 37 | 38 | int vector_add(struct vector *vec, void *item); 39 | 40 | int vector_apply(struct vector *vec, void (*func)(void *)); 41 | 42 | int vector_delete(struct vector *vec, size_t index, void **item); 43 | 44 | int vector_free(struct vector *vec); 45 | 46 | int vector_get(struct vector *vec, size_t index, void **item); 47 | 48 | int vector_init(struct vector *vec); 49 | 50 | int vector_reserve(struct vector *vec, size_t size); 51 | 52 | int vector_set(struct vector *vec, size_t index, void *item); 53 | 54 | int vector_swap(struct vector *vec, size_t idx1, size_t idx2); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /c_struct/vector_main.c: -------------------------------------------------------------------------------- 1 | 2 | #define _CRT_SECURE_NO_WARNINGS 3 | 4 | #include "vector.h" 5 | #include 6 | #include 7 | 8 | 9 | void test_Vector() 10 | { 11 | struct vector* alist=(struct vector*)malloc(sizeof(struct vector)); 12 | vector_init(alist); 13 | 14 | int i = 0; 15 | for (i = 0; i < 15; i++) 16 | { 17 | 18 | char* tmp = (char*)malloc(sizeof(char)* 512); 19 | memset(tmp, 0, sizeof(char)* 512); 20 | sprintf(tmp, "hehe%d", i); 21 | printf("%s\n", tmp); 22 | vector_add(alist, tmp); 23 | } 24 | 25 | int len = vector_count(alist); 26 | for (i = 0; i < len; i++) 27 | { 28 | char* tmp; 29 | vector_get(alist, i,&tmp); 30 | printf("%s\n",tmp); 31 | } 32 | 33 | vector_free(alist); 34 | 35 | 36 | 37 | } 38 | 39 | int main(int argc, char* argv[]) 40 | { 41 | 42 | test_Vector(); 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /c_struct/vector_matteckert.c: -------------------------------------------------------------------------------- 1 | #include "vector_matteckert.h" 2 | 3 | #include 4 | #include 5 | 6 | #define ELEM(i) ((char *) (v->elem) + (i) * (v->size)) 7 | 8 | struct vector { 9 | size_t plen; 10 | size_t llen; 11 | size_t size; 12 | void (*free)(void *); 13 | void *elem; 14 | }; 15 | 16 | static bool brim(vector v); 17 | static bool grow(vector v); 18 | 19 | vector vector_new(size_t hint, size_t size, void (*freefn)(void *)) { 20 | vector v = malloc(sizeof *v); 21 | if (!v) return NULL; 22 | v->plen = hint ? hint : 16; 23 | v->llen = 0; 24 | v->size = size ? size : 1; 25 | v->free = freefn; 26 | v->elem = malloc(v->plen * v->size); 27 | if (!v->elem) { free(v); return NULL; } 28 | return v; 29 | } 30 | 31 | void vector_free(vector v) { 32 | if (v->free) 33 | for (size_t i = 0; i < v->llen; i++) 34 | v->free(*(void **)(ELEM(i))); 35 | free(v->elem); 36 | free(v); 37 | } 38 | 39 | size_t vector_size(vector v) { 40 | if (!v) return 0; 41 | return v->llen; 42 | } 43 | 44 | bool vector_empty(vector v) { 45 | if (!v) return true; 46 | return v->llen ? false : true; 47 | } 48 | 49 | bool vector_clear(vector v) { 50 | if (!v) return false; 51 | if (v->free) 52 | for (size_t i = 0; i < v->llen; v++) 53 | v->free(*(void **)(ELEM(i))); 54 | v->llen = 0; 55 | return true; 56 | } 57 | 58 | bool vector_get(vector v, size_t i, void *elem) { 59 | if (!v || i >= v->llen || !elem) return false; 60 | memcpy(elem, ELEM(i), v->size); 61 | return true; 62 | } 63 | 64 | bool vector_remove(vector v, size_t i, void *elem) { 65 | if (!v || i >= v->llen) return false; 66 | if (elem) memcpy(elem, ELEM(i), v->size); 67 | else if (v->free) v->free(*(void **)(ELEM(i))); 68 | memmove(ELEM(i), ELEM(i+1), (v->llen-- - i + v->size)); 69 | return true; 70 | } 71 | 72 | bool vector_add(vector v, void *elem) { 73 | if (!v) return false; 74 | if (brim(v) && !grow(v)) return false; 75 | memcpy(ELEM(v->llen++), elem, v->size); 76 | return true; 77 | } 78 | 79 | bool vector_insert(vector v, size_t i, void *elem) { 80 | if (!v || i >= v->llen) return false; 81 | if (brim(v) && !grow(v)) return false; 82 | memmove(ELEM(i+1), ELEM(i), (v->llen++ - i + v->size)); 83 | memcpy(ELEM(i), elem, v->size); 84 | return true; 85 | } 86 | 87 | static bool brim(vector v) { return v->llen == v->plen ? true : false; } 88 | 89 | static bool grow(vector v) { 90 | size_t more = v->plen * 2; 91 | void *temp = realloc(v->elem, more * v->size); 92 | if (!temp) return false; 93 | v->plen = more; 94 | v->elem = temp; 95 | return true; 96 | } 97 | -------------------------------------------------------------------------------- /c_struct/vector_matteckert.h: -------------------------------------------------------------------------------- 1 | #ifndef VECTOR_H 2 | #define VECTOR_H 3 | 4 | #include 5 | #include 6 | 7 | /* An opaque pointer to a vector abstract data type. */ 8 | typedef struct vector *vector; 9 | 10 | /* Allocate, initialize, and return a new vector that stores elements of size 11 | * `size`. If `freefn` is not NULL, it is used to free individual elements 12 | * upon removal. Note that `freefn` will be called on already free'd memory 13 | * if elements point to the same memory location. */ 14 | vector vector_new(size_t hint, size_t size, void (*freefn)(void *)); 15 | 16 | /* Free memory allocated by `vector_new`. If `v` has a non-NULL `free` 17 | * function, the remaining elements of `v` are passed to this function. */ 18 | void vector_free(vector v); 19 | 20 | /* Get the logical size of `v`. */ 21 | size_t vector_size(vector v); 22 | 23 | /* Add `elem` to the end of `v`. */ 24 | bool vector_add(vector v, void *elem); 25 | 26 | /* Store the element at index `i` in `elem`. */ 27 | bool vector_get(vector v, size_t i, void *elem); 28 | 29 | /* Remove the element at index `i`. If `elem` is not NULL, the object removed 30 | * is stored in `elem`. If `elem` is NULL and `v` has a non-NULL `free` 31 | * function, the element at index `i` is passed to this function. */ 32 | bool vector_remove(vector v, size_t i, void *elem); 33 | 34 | /* Insert the element `elem` at index `i`. The indices of elements after the 35 | * insertion point increment by one. */ 36 | bool vector_insert(vector v, size_t i, void *elem); 37 | 38 | /* Return `true` if `v` is empty; otherwise, return `false`. */ 39 | bool vector_empty(vector v); 40 | 41 | /* Remove all elements from `v`. If `v` has a non-NULL `free` function, the 42 | * each element of `v` is passed to this function. */ 43 | bool vector_clear(vector v); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /c_struct/vector_matteckert.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/c_struct/vector_matteckert.zip -------------------------------------------------------------------------------- /c_struct/vector_matteckert_main.c: -------------------------------------------------------------------------------- 1 | 2 | #define _CRT_SECURE_NO_WARNINGS 3 | 4 | #include "vector_matteckert.h" 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | static void json_object_array_entry_free(void *data) 11 | { 12 | //json_object_put((struct json_object*)data); 13 | //printf("json_object_array_entry_free=%s\n", data); 14 | } 15 | 16 | void test_Vector() 17 | { 18 | 19 | struct vector* alist = vector_new(0, 1, json_object_array_entry_free); 20 | 21 | int i = 0; 22 | for (i = 0; i < 15; i++) 23 | { 24 | 25 | char* tmp = (char*)malloc(sizeof(char)* 512); 26 | memset(tmp, 0, sizeof(char)* 512); 27 | sprintf(tmp, "hehe%d", i); 28 | printf("%s\n", tmp); 29 | vector_add(alist, tmp); 30 | } 31 | 32 | int len = vector_size(alist); 33 | for (i = 0; i < len; i++) 34 | { 35 | char* tmp=(char*)malloc(sizeof(char)*512); 36 | vector_get(alist, i, &tmp); 37 | printf("%s\n", tmp); 38 | } 39 | 40 | vector_free(alist); 41 | 42 | 43 | } 44 | 45 | int main(int argc, char* argv[]) 46 | { 47 | 48 | test_Vector(); 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /cbigint/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Libraries 8 | *.lib 9 | *.a 10 | 11 | # Shared objects (inc. Windows DLLs) 12 | *.dll 13 | *.so 14 | *.so.* 15 | *.dylib 16 | 17 | # Executables 18 | *.exe 19 | *.out 20 | *.app 21 | *.i*86 22 | *.x86_64 23 | *.hex 24 | 25 | *.swp 26 | -------------------------------------------------------------------------------- /cbigint/BigInt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "BigInt.h" 8 | 9 | #define MAX(x, y) ((x) > (y) ? (x) : (y)) 10 | 11 | BigInt* BigInt_construct(int value) { 12 | 13 | BigInt* new_big_int = malloc(sizeof(BigInt)); 14 | 15 | if(value < 0) { 16 | new_big_int->is_negative = 1; 17 | value *= -1; 18 | } else { 19 | new_big_int->is_negative = 0; 20 | } 21 | 22 | new_big_int->num_digits = floor(log10(value)) + 1; 23 | 24 | // Special case for 0 25 | if(new_big_int->num_digits == 0) { 26 | new_big_int->num_digits = 1; 27 | } 28 | 29 | new_big_int->num_allocated_digits = new_big_int->num_digits; 30 | new_big_int->digits = malloc(new_big_int->num_allocated_digits * sizeof(unsigned char)); 31 | 32 | int i; 33 | for(i = 0; i < new_big_int->num_digits; i++) { 34 | new_big_int->digits[i] = value % 10; 35 | value /= 10; 36 | } 37 | 38 | return new_big_int; 39 | } 40 | 41 | void BigInt_free(BigInt* big_int) { 42 | free(big_int->digits); 43 | free(big_int); 44 | } 45 | 46 | void BigInt_assign(BigInt* target, const BigInt* source) 47 | { 48 | BigInt_ensure_digits(target, source->num_digits); 49 | 50 | int i; 51 | for(i = 0; i < source->num_digits; ++i) { 52 | target->digits[i] = source->digits[i]; 53 | } 54 | 55 | target->is_negative = source->is_negative; 56 | target->num_digits = source->num_digits; 57 | } 58 | 59 | void BigInt_assign_int(BigInt* target, const int source) { 60 | int value = source; 61 | 62 | if(value < 0) { 63 | target->is_negative = 1; 64 | value *= -1; 65 | } else { 66 | target->is_negative = 0; 67 | } 68 | 69 | target->num_digits = floor(log10(value)) + 1; 70 | 71 | // Special case for 0 72 | if(target->num_digits == 0) { 73 | target->num_digits = 1; 74 | } 75 | 76 | BigInt_ensure_digits(target, target->num_digits); 77 | 78 | int i; 79 | for(i = 0; i < target->num_digits; i++) { 80 | target->digits[i] = value % 10; 81 | value /= 10; 82 | } 83 | } 84 | 85 | int BigInt_compare(const BigInt* a, const BigInt* b) { 86 | // Quick return if one is negative and the other isn't 87 | if(a->num_digits > 0 || a->digits[0] > 0 || b->num_digits > 0 || b->digits[0] > 0) { 88 | if (a->is_negative && !b->is_negative) { 89 | return -1; 90 | } else if (!a->is_negative && b->is_negative) { 91 | return 1; 92 | } 93 | } 94 | 95 | return a->is_negative ? BigInt_compare_digits(b, a) : BigInt_compare_digits(a, b); 96 | } 97 | 98 | int BigInt_compare_digits(const BigInt* a, const BigInt* b) { 99 | // Not looking at the sign here, comparing the digits only. 100 | 101 | // Quick return if one number has more digits than the other 102 | if(a->num_digits > b->num_digits) { 103 | return 1; 104 | } else if(a->num_digits < b->num_digits) { 105 | return -1; 106 | } 107 | 108 | // Both have the same number of digits, so we actually have to loop through until we 109 | // find one that doesn't match. 110 | int i; 111 | for(i = a->num_digits - 1; i >= 0; --i) { 112 | if(a->digits[i] > b->digits[i]) { 113 | return 1; 114 | } else if(a->digits[i] < b->digits[i]) { 115 | return -1; 116 | } 117 | } 118 | 119 | // All digits match; numbers are equal 120 | return 0; 121 | } 122 | 123 | void BigInt_add(BigInt* big_int, const BigInt* addend) { 124 | if(big_int->is_negative == addend->is_negative) { 125 | // Sign will never change in this case so just leave 126 | // it as-is. 127 | BigInt_add_digits(big_int, addend); 128 | } else { 129 | // Figure out the sign. Need to do this before calculating the digits of 130 | // the digits result because changing those in big_int will affect the result 131 | // of the compare. 132 | unsigned int result_is_negative = BigInt_compare_digits(big_int, addend) > 0 ? 133 | big_int->is_negative : addend->is_negative; 134 | 135 | BigInt_subtract_digits(big_int, addend); 136 | big_int->is_negative = result_is_negative; 137 | } 138 | } 139 | 140 | void BigInt_add_int(BigInt* big_int, const int addend) { 141 | BigInt* big_int_addend = BigInt_construct(addend); 142 | BigInt_add(big_int, big_int_addend); 143 | BigInt_free(big_int_addend); 144 | } 145 | 146 | void BigInt_add_digits(BigInt* big_int, const BigInt* addend) { 147 | unsigned int digits_needed = MAX(big_int->num_digits, addend->num_digits) + 1; 148 | BigInt_ensure_digits(big_int, digits_needed); 149 | 150 | int i; 151 | int carry = 0; 152 | for(i = 0; i < addend->num_digits || carry > 0; ++i) { 153 | // Append another digit if necessary 154 | if(i == big_int->num_digits) { 155 | ++big_int->num_digits; 156 | big_int->digits[i] = 0; 157 | } 158 | 159 | unsigned int addend_digit = i < addend->num_digits ? addend->digits[i] : 0; 160 | unsigned int total = big_int->digits[i] + addend_digit + carry; 161 | big_int->digits[i] = total % 10; 162 | carry = (total >= 10) ? 1 : 0; 163 | } 164 | } 165 | 166 | void BigInt_subtract(BigInt* big_int, const BigInt* to_subtract) { 167 | // Figure out the sign. Need to do this before calculating the digits of 168 | // the digits result because changing those in big_int will affect the result 169 | // of the compare. 170 | unsigned int result_is_negative = BigInt_compare(big_int, to_subtract) > 0 ? 0 : 1; 171 | 172 | // Calculate the digits 173 | if(big_int->is_negative == to_subtract->is_negative) { 174 | BigInt_subtract_digits(big_int, to_subtract); 175 | } else { 176 | BigInt_add_digits(big_int, to_subtract); 177 | } 178 | 179 | // Figure out the sign 180 | big_int->is_negative = result_is_negative; 181 | } 182 | 183 | 184 | void BigInt_subtract_int(BigInt* big_int, const int to_subtract) { 185 | BigInt* big_int_to_subtract = BigInt_construct(to_subtract); 186 | BigInt_subtract(big_int, big_int_to_subtract); 187 | BigInt_free(big_int_to_subtract); 188 | } 189 | 190 | void BigInt_subtract_digits(BigInt* big_int, const BigInt* to_subtract) { 191 | 192 | unsigned int digits_needed = MAX(big_int->num_digits, to_subtract->num_digits) + 1; 193 | BigInt_ensure_digits(big_int, digits_needed); 194 | 195 | // Determine the larger int. This will go on "top" 196 | // of the subtraction. Sign doesn't matter here since we've already 197 | // determined the sign of the final result above. 198 | unsigned char* greater_int_digits; 199 | unsigned char* smaller_int_digits; 200 | unsigned int smaller_int_num_digits; 201 | unsigned int greater_int_num_digits; 202 | 203 | if(BigInt_compare_digits(big_int, to_subtract) > 0) { 204 | greater_int_digits = big_int->digits; 205 | greater_int_num_digits = big_int->num_digits; 206 | smaller_int_digits = to_subtract->digits; 207 | smaller_int_num_digits = to_subtract->num_digits; 208 | } else { 209 | greater_int_digits = to_subtract->digits; 210 | greater_int_num_digits = to_subtract->num_digits; 211 | smaller_int_digits = big_int->digits; 212 | smaller_int_num_digits = big_int->num_digits; 213 | } 214 | 215 | // Actually carry out the subtraction. 216 | int i; 217 | int carry = 0; 218 | big_int->num_digits = 1; 219 | 220 | for(i = 0; i < greater_int_num_digits; ++i) { 221 | int new_digit; 222 | if(i < smaller_int_num_digits) { 223 | new_digit = (int)greater_int_digits[i] - (int)smaller_int_digits[i] + carry; 224 | } else { 225 | new_digit = (int)greater_int_digits[i] + carry; 226 | } 227 | 228 | // Carry 10 from the next digit if necessary 229 | if(new_digit < 0) { 230 | carry = -1; 231 | new_digit += 10; 232 | } else { 233 | carry = 0; 234 | } 235 | 236 | assert(new_digit >= 0); 237 | big_int->digits[i] = new_digit; 238 | if(new_digit != 0) { 239 | big_int->num_digits = i + 1; 240 | } 241 | } 242 | 243 | assert(carry == 0); 244 | } 245 | 246 | // Multiply using the pencil and paper method. Complexity is O(n*m) where n, m are 247 | // the number of digits in big_int and multiplier, respectively. 248 | void BigInt_multiply(BigInt* big_int, const BigInt* multiplier) { 249 | 250 | // Need to keep track of the result in a separate variable because we need 251 | // big_int to retain its original value throughout the course of the calculation. 252 | BigInt* result = BigInt_construct(0); 253 | 254 | // addend will hold the amount to be added to the result for each step of 255 | // the multiplication. 256 | BigInt* addend = BigInt_construct(0); 257 | 258 | unsigned int digits_needed = big_int->num_digits + addend->num_digits + 1; 259 | BigInt_ensure_digits(addend, digits_needed); 260 | 261 | int i, j; 262 | int carry = 0; 263 | for(i = 0; i < multiplier->num_digits; ++i) { 264 | 265 | if(i > 0) { 266 | addend->num_digits = i; 267 | addend->digits[i - 1] = 0; 268 | } 269 | 270 | for(j = 0; j < big_int->num_digits || carry > 0; ++j) { 271 | if(j + i == addend->num_digits) { 272 | ++addend->num_digits; 273 | } 274 | 275 | assert(digits_needed >= j + 1); 276 | 277 | int total; 278 | if(j < big_int->num_digits) { 279 | total = (big_int->digits[j] * multiplier->digits[i]) + carry; 280 | } else { 281 | total = carry; 282 | } 283 | 284 | addend->digits[i + j] = total % 10; 285 | carry = total / 10; 286 | } 287 | 288 | BigInt_add(result, addend); 289 | } 290 | 291 | result->is_negative = big_int->is_negative != multiplier->is_negative; 292 | 293 | // Place the result in big_int and clean things up 294 | BigInt_assign(big_int, result); 295 | BigInt_free(result); 296 | BigInt_free(addend); 297 | } 298 | 299 | void BigInt_multiply_int(BigInt* big_int, const int multiplier) { 300 | BigInt* big_int_multiplier = BigInt_construct(multiplier); 301 | BigInt_multiply(big_int, big_int_multiplier); 302 | BigInt_free(big_int_multiplier); 303 | } 304 | 305 | int BigInt_to_int(const BigInt* big_int) { 306 | int value = 0; 307 | int tens_multiplier = 1; 308 | 309 | int i; 310 | for(i = 0; i < big_int->num_digits; i++) { 311 | value += big_int->digits[i] * tens_multiplier; 312 | tens_multiplier *= 10; 313 | } 314 | 315 | if (big_int->is_negative) { 316 | value *= -1; 317 | } 318 | 319 | return value; 320 | 321 | } 322 | 323 | void BigInt_print(const BigInt* big_int) { 324 | int i; 325 | for(i = big_int->num_digits - 1; i >= 0; --i) { 326 | printf("%i", big_int->digits[i]); 327 | } 328 | } 329 | 330 | void BigInt_ensure_digits(BigInt* big_int, unsigned int digits_needed) { 331 | if(big_int->num_allocated_digits < digits_needed) { 332 | unsigned char* digits = big_int->digits; 333 | 334 | big_int->digits = malloc(digits_needed * sizeof(unsigned char)); 335 | memcpy(big_int->digits, digits, big_int->num_digits); 336 | big_int->num_allocated_digits = digits_needed; 337 | 338 | free(digits); 339 | } 340 | } 341 | 342 | -------------------------------------------------------------------------------- /cbigint/BigInt.h: -------------------------------------------------------------------------------- 1 | #ifndef BIG_INT_H 2 | #define BIG_INT_H 3 | 4 | #ifndef NULL 5 | #define NULL 0 6 | #endif 7 | 8 | // Specifies the amount of logging in the unit test suite. 9 | // Set to 0 to disable all logging. 10 | // Set to 1 for minimal logging. 11 | // Set to 2 for verbose logging. 12 | #define BIGINT_TEST_LOGGING 1 13 | 14 | typedef struct BigInt { 15 | unsigned char* digits; // Array of digits 0-9. Greater indices hold more significant digits. 16 | unsigned int num_digits; // Number of digits actually in the number. 17 | unsigned int num_allocated_digits; // digits array has space for this many digits 18 | int is_negative; // Nonzero if this BigInt is negative, zero otherwise. 19 | } BigInt; 20 | 21 | //============================================================================ 22 | // Construction and assignment 23 | //============================================================================ 24 | 25 | // Returns a pointer to a new BigInt initialized to the specified value. 26 | // Caller is responsible for freeing the new BigInt with a 27 | // corresponding call to BigInt_free. 28 | BigInt* BigInt_construct(int value); 29 | 30 | // Frees the memory for a BigInt allocated using BigInt_construct. 31 | void BigInt_free(BigInt* big_int); 32 | 33 | ///Sets the value of the target BigInt to the value of the source BigInt. 34 | // Assumes that target and source already point to valid BigInts. 35 | void BigInt_assign(BigInt* target, const BigInt* source); 36 | 37 | ///Sets the value of the target BigInt to the value of the source int. 38 | void BigInt_assign_int(BigInt* target, const int source); 39 | 40 | //============================================================================ 41 | // Basic mathematical operations 42 | //============================================================================ 43 | 44 | // Returns -1 if a < b, 0 if a == b, 1 if a > b 45 | int BigInt_compare(const BigInt* a, const BigInt* b); 46 | 47 | // Adds the value in addend to big_int. Places the result in big_int. 48 | void BigInt_add(BigInt* big_int, const BigInt* addend); 49 | void BigInt_add_int(BigInt* big_int, const int addend); 50 | 51 | // Subtracts the value of to_subtract from big_int. 52 | // Places the result in big_int. 53 | void BigInt_subtract(BigInt* big_int, const BigInt* to_subtract); 54 | void BigInt_subtract_int(BigInt* big_int, const int to_subtract); 55 | 56 | // Multiplies the value in big_int by multiplier. Places the 57 | // result in big_int. 58 | void BigInt_multiply(BigInt* big_int, const BigInt* multiplier); 59 | void BigInt_multiply_int(BigInt* big_int, const int multiplier); 60 | 61 | // Returns the value of big_int as an integer. Requires that the 62 | // value of big_int fits within the size of an int on the target 63 | // environment. Result is undefined if this is not the case. 64 | int BigInt_to_int(const BigInt* big_int); 65 | 66 | // Prints the contents of big_int to stdout. 67 | void BigInt_print(const BigInt* big_int); 68 | 69 | //============================================================================ 70 | // Internal helpers 71 | //============================================================================ 72 | 73 | // Ensure that big_int has space allocated for at least digits_needed digits. 74 | void BigInt_ensure_digits(BigInt* big_int, unsigned int digits_needed); 75 | 76 | // Performs an unsigned comparison of the two BigInt parameters; that is, the 77 | // comparison is of their absolute values. Returns 1 if |a| > |b|, 0 if |a| == |b|, 78 | // and -1 if |a| < |b|. 79 | int BigInt_compare_digits(const BigInt* a, const BigInt* b); 80 | 81 | // Performs an unsigned addition of to_add to big_int; adds the digits without regard 82 | // for the sign of either parameter. 83 | void BigInt_add_digits(BigInt* big_int, const BigInt* to_add); 84 | 85 | // Performs an unsigned subtraction of to_subtract from big_int; subtracts the digits 86 | // without regard for the sign of either parameter. 87 | void BigInt_subtract_digits(BigInt* big_int, const BigInt* to_subtract); 88 | 89 | //============================================================================ 90 | // Unit tests 91 | //============================================================================ 92 | 93 | typedef enum { ADD, ADD_INT, SUBTRACT, SUBTRACT_INT, MULTIPLY, MULTIPLY_INT, 94 | COMPARE, OPERATION_TYPE_MAX} OPERATION_TYPE; 95 | extern const char* OPERATION_NAMES[]; 96 | 97 | // Used to cast various BigInt functions to a generic type that can 98 | // be passed through the test helpers BigInt_test_permutations and 99 | // BigInt_test_single_operation. The function pointers are cast 100 | // back to the correct type in BigInt_test_single_operation using 101 | // the specified OPERATION_TYPE. 102 | typedef void*(*Generic_function)(void*); 103 | 104 | void BigInt_test_basic(); 105 | void BigInt_test_construct(int value); 106 | void BigInt_test_operations(int a, int b); 107 | void BigInt_test_permutations(Generic_function BigInt_operation_to_test, 108 | OPERATION_TYPE operation_type, int a, int b); 109 | void BigInt_test_single_operation(Generic_function BigInt_operation_to_test, 110 | OPERATION_TYPE operation_type, int a, int b); 111 | 112 | #endif // BIG_INT_H 113 | 114 | -------------------------------------------------------------------------------- /cbigint/BigInt_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "BigInt.h" 5 | 6 | const char* OPERATION_NAMES[] = {"Addition", "Addition with int", 7 | "Subtraction", "Subtraction with int", "Multiplication", 8 | "Multiplication with int", "Comparison"}; 9 | 10 | void BigInt_test_basic() { 11 | 12 | if(BIGINT_TEST_LOGGING > 0) { 13 | printf("Testing construction\n"); 14 | } 15 | BigInt_test_construct(0); 16 | BigInt_test_construct(1); 17 | BigInt_test_construct(-1); 18 | BigInt_test_construct(2); 19 | BigInt_test_construct(10); 20 | BigInt_test_construct(100); 21 | BigInt_test_construct(1000000000); 22 | BigInt_test_construct(1000000001); 23 | BigInt_test_construct(990000000); 24 | 25 | // Ensure that reallocating digits doesn't make us 26 | // lose data. 27 | if(BIGINT_TEST_LOGGING > 0) { 28 | printf("Testing digit reallocation\n"); 29 | } 30 | BigInt* big_int = BigInt_construct(42); 31 | assert(BigInt_to_int(big_int) == 42); 32 | BigInt_ensure_digits(big_int, 1000); 33 | assert(BigInt_to_int(big_int) == 42); 34 | BigInt_ensure_digits(big_int, 1); 35 | assert(BigInt_to_int(big_int) == 42); 36 | BigInt_free(big_int); 37 | 38 | // Test addition, subtraction, and comparison for all positive and 39 | // negative permutations of these integers 40 | if(BIGINT_TEST_LOGGING > 0) { 41 | printf("Testing basic 2-argument operations\n"); 42 | } 43 | BigInt_test_operations(0, 0); 44 | BigInt_test_operations(1, 1); 45 | BigInt_test_operations(5, 5); 46 | BigInt_test_operations(5, 6); 47 | BigInt_test_operations(10, 2); 48 | BigInt_test_operations(14, 16); 49 | BigInt_test_operations(16, 18); 50 | BigInt_test_operations(11, 111); 51 | BigInt_test_operations(50, 50); 52 | BigInt_test_operations(51, 50); 53 | BigInt_test_operations(64, 46); 54 | BigInt_test_operations(1000, 999); 55 | BigInt_test_operations(30, 28); 56 | BigInt_test_operations(1, 50); 57 | BigInt_test_operations(100, 101); 58 | BigInt_test_operations(1000, 999); 59 | BigInt_test_operations(123456, 1234); 60 | BigInt_test_operations(999999999, 1); 61 | BigInt_test_operations(0, 12345678); 62 | BigInt_test_operations(1000, 1); 63 | BigInt_test_operations(2546, 2546); 64 | BigInt_test_operations(1234, 4321); 65 | } 66 | 67 | void BigInt_test_construct(int value) { 68 | BigInt* big_int = BigInt_construct(value); 69 | assert(BigInt_to_int(big_int) == value); 70 | BigInt_free(big_int); 71 | } 72 | 73 | void BigInt_test_operations(int a, int b) { 74 | 75 | OPERATION_TYPE operation_type; 76 | 77 | for(operation_type = 0; operation_type < OPERATION_TYPE_MAX; operation_type++) { 78 | switch(operation_type) { 79 | case ADD: 80 | BigInt_test_permutations((Generic_function)BigInt_add, operation_type, a, b); 81 | break; 82 | case ADD_INT: 83 | BigInt_test_permutations((Generic_function)BigInt_add_int, operation_type, a, b); 84 | break; 85 | case SUBTRACT: 86 | BigInt_test_permutations((Generic_function)BigInt_subtract, operation_type, a, b); 87 | break; 88 | case SUBTRACT_INT: 89 | BigInt_test_permutations((Generic_function)BigInt_subtract_int, operation_type, a, b); 90 | break; 91 | case MULTIPLY: 92 | BigInt_test_permutations((Generic_function)BigInt_multiply, operation_type, a, b); 93 | break; 94 | case MULTIPLY_INT: 95 | BigInt_test_permutations((Generic_function)BigInt_multiply_int, operation_type, a, b); 96 | break; 97 | case COMPARE: 98 | BigInt_test_permutations((Generic_function)BigInt_compare, operation_type, a, b); 99 | break; 100 | default: 101 | printf("Unsupported operation: %i\n", operation_type); 102 | assert(0); 103 | } 104 | } 105 | } 106 | 107 | // Calls the specified BigInt 2-operand function for all 108 | // permutations of positive, negative, and order-reversals 109 | // of the values a and b. 110 | void BigInt_test_permutations(Generic_function BigInt_operation_to_test, 111 | OPERATION_TYPE operation_type, int a, int b) { 112 | 113 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, a, b); 114 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, -a, b); 115 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, a, -b); 116 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, -a, -b); 117 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, b, a); 118 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, -b, a); 119 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, b, -a); 120 | BigInt_test_single_operation(BigInt_operation_to_test, operation_type, -b, -a); 121 | } 122 | 123 | void BigInt_test_single_operation(Generic_function BigInt_operation_to_test, 124 | OPERATION_TYPE operation_type, int a, int b) { 125 | 126 | if(BIGINT_TEST_LOGGING > 1) { 127 | printf("Testing %s for %i, %i\n", OPERATION_NAMES[operation_type], a, b); 128 | } 129 | 130 | BigInt* big_int_a = BigInt_construct(a); 131 | BigInt* big_int_b = BigInt_construct(b); 132 | 133 | int result; 134 | 135 | switch(operation_type) { 136 | case ADD: 137 | case SUBTRACT: 138 | case MULTIPLY: 139 | ((void(*)(BigInt*, const BigInt*))(*BigInt_operation_to_test))(big_int_a, big_int_b); 140 | result = BigInt_to_int(big_int_a); 141 | break; 142 | case ADD_INT: 143 | case SUBTRACT_INT: 144 | case MULTIPLY_INT: 145 | ((void(*)(BigInt*, const int))(*BigInt_operation_to_test))(big_int_a, b); 146 | result = BigInt_to_int(big_int_a); 147 | break; 148 | case COMPARE: 149 | result = ((int(*)(const BigInt*, const BigInt*))(*BigInt_operation_to_test))(big_int_a, big_int_b); 150 | break; 151 | default: 152 | printf("Unsupported operation\n"); 153 | assert(0); 154 | } 155 | 156 | if(BIGINT_TEST_LOGGING > 1) { 157 | printf("%s result: %i\n", OPERATION_NAMES[operation_type], result); 158 | } 159 | 160 | switch(operation_type) { 161 | case ADD: 162 | case ADD_INT: 163 | assert(result == a + b); 164 | break; 165 | case SUBTRACT: 166 | case SUBTRACT_INT: 167 | assert(result == a - b); 168 | break; 169 | case MULTIPLY: 170 | case MULTIPLY_INT: 171 | assert(result == a * b); 172 | break; 173 | case COMPARE: 174 | assert((a > b) ? (result == 1) : (a < b) ? (result == -1) : (result == 0)); 175 | break; 176 | default: 177 | printf("Unsupported operation\n"); 178 | assert(0); 179 | } 180 | 181 | BigInt_free(big_int_a); 182 | BigInt_free(big_int_b); 183 | } 184 | 185 | -------------------------------------------------------------------------------- /cbigint/README.md: -------------------------------------------------------------------------------- 1 | # BigInt 2 | 3 | C library for operations with signed integers of arbitrary size. 4 | 5 | ## Introduction 6 | 7 | BigInt supports various basic mathematical operations: addition, subtraction, multiplication, and comparison. The primary use case is when very large numbers are needed; BigInts can contain up to the number of digits as the maximum value of an unsigned long (typically 2^32 - 1 on a 32-bit machine). 8 | 9 | A BigInt is a struct with the following fields: 10 | * digits -- An array of digits 0-9. The lowest index is the least significant digit. 11 | * num_digits -- The number of digits in the digits array. 12 | * is_negative -- Nonzero if the BigInt is negative, zero if the BigInt is positive. 13 | * num_allocated_digits -- The amount of space allocated for digits; caller doesn't need to care about this. 14 | 15 | ## Usage 16 | 17 | Obtain a pointer to a new BigInt through a call to BigInt_construct: 18 | ``` 19 | BigInt* new_big_int = BigInt_construct(42); // Obtains a BigInt initialized to 42 20 | ``` 21 | 22 | The caller is responsible for freeing a BigInt allocated with BigInt_construct with a call to BigInt_free: 23 | ``` 24 | BigInt_free(new_big_int); 25 | ``` 26 | 27 | The contents of a BigInt can be printed to stdout with a call to BigInt_print. 28 | ``` 29 | BigInt_print(big_int); 30 | ``` 31 | 32 | Get a normal int back from a BigInt with using BigInt_to_int; but be careful; the BigInt must fit in an int type! 33 | ``` 34 | int a = BigInt_to_int(big_int); 35 | ``` 36 | 37 | BigInt operations take two BigInt parameters and place the result in the first parameter: 38 | ``` 39 | BigInt* a = BigInt_construct(15); 40 | BigInt* b = BigInt_construct(-20); 41 | BigInt_add(a, b); 42 | BigInt_print(a); // Prints -5 43 | ``` 44 | 45 | The exception is BigInt_compare; this takes two BigInt parameters, changes neither, and returns the value of the comparison: 46 | ``` 47 | BigInt a = BigInt_construct(15); 48 | BigInt b = BigInt_construct(-20); 49 | printf("%i\n", BigInt_compare(a, b)); // prints 1 50 | printf("%i\n", BigInt_compare(b, a)); // prints -1 51 | printf("%i\n", BigInt_compare(a, a)); // prints 0 52 | ``` 53 | -------------------------------------------------------------------------------- /cbigint/demo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "BigInt.h" 4 | 5 | // Demo of some basic BigInt functionality 6 | 7 | int main() { 8 | // Obtain a BigInt initialized to 42 9 | BigInt* new_big_int = BigInt_construct(42); 10 | 11 | // Get a normal int back (the BigInt must fit in an int type) 12 | int as_int = BigInt_to_int(new_big_int); 13 | 14 | // Print to stdout with BigInt_print 15 | printf("BigInt is: "); 16 | BigInt_print(new_big_int); 17 | printf("\nAs int: %i\n", as_int); 18 | 19 | // The caller is responsible for freeing a BigInt allocated with 20 | // BigInt_construct with a call to BigInt_free: 21 | BigInt_free(new_big_int); 22 | 23 | // BigInt operations take two BigInt parameters and place the result in the first parameter: 24 | BigInt* a = BigInt_construct(15); 25 | BigInt* b = BigInt_construct(-20); 26 | BigInt_add(a, b); 27 | printf("Addition result: "); 28 | BigInt_print(a); // Prints -5 29 | printf("\n"); 30 | 31 | // The exception is BigInt_compare; this takes two BigInt parameters, changes neither, and returns the value of the comparison: 32 | BigInt_assign_int(a, 15); 33 | BigInt_assign_int(b, -20); 34 | printf("Comparison results:\n"); 35 | printf("%i\n", BigInt_compare(a, b)); // prints 1 36 | printf("%i\n", BigInt_compare(b, a)); // prints -1 37 | printf("%i\n", BigInt_compare(a, a)); // prints 0 38 | 39 | BigInt_free(a); 40 | BigInt_free(b); 41 | 42 | return 0; 43 | } 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /cbigint/makefile: -------------------------------------------------------------------------------- 1 | all: test demo 2 | 3 | test: BigInt.o BigInt_test.o test.o 4 | gcc -lm -o test BigInt.o BigInt_test.o test.o 5 | 6 | demo: demo.o BigInt.o 7 | gcc -lm -o demo demo.c BigInt.o 8 | 9 | BigInt.o: BigInt.c BigInt.h 10 | gcc -c BigInt.c 11 | 12 | test.o: test.c 13 | gcc -c test.c 14 | 15 | demo.o: demo.c 16 | gcc -c test.c 17 | 18 | BigInt_test.o: BigInt_test.c 19 | gcc -c BigInt_test.c 20 | 21 | clean: 22 | rm -f *.o test demo 23 | 24 | -------------------------------------------------------------------------------- /cbigint/test.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "BigInt.h" 5 | 6 | // Run BigInt unit tests 7 | 8 | int main() { 9 | 10 | BigInt_test_basic(); 11 | 12 | return 0; 13 | } 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /cppbigint/CBigInt.cpp: -------------------------------------------------------------------------------- 1 | #include "CBigInt.h" 2 | 3 | CBigInt 4 | operator+(const CBigInt &a, const CBigInt &b) 5 | { 6 | if (a.isNaN() || b.isNaN()) 7 | return CBigInt::NaN(); 8 | 9 | if (a.isNegative() || b.isNegative()) { 10 | if (! a.isNegative()) 11 | return ( a - (-b)); 12 | else if (! b.isNegative()) 13 | return -((-a) - b ); 14 | else 15 | return -((-a) + (-b)); 16 | } 17 | 18 | if (a.is_value_ || b.is_value_) { 19 | if (! a.is_value_) { 20 | CBigInt b1 = b; 21 | 22 | return a + b1.convString(); 23 | } 24 | else if (! b.is_value_) { 25 | CBigInt a1 = a; 26 | 27 | return a1.convString() + b; 28 | } 29 | else { 30 | ulong value1 = a.value_ + b.value_; 31 | 32 | if (value1 < std::max(a.value_, b.value_) || ((long) value1) < 0) { 33 | CBigInt a1 = a; 34 | CBigInt b1 = b; 35 | 36 | return a1.convString() + b1.convString(); 37 | } 38 | 39 | return CBigInt(value1); 40 | } 41 | } 42 | 43 | CBigInt c; 44 | 45 | c.str_ = "0"; 46 | c.is_value_ = false; 47 | 48 | int size1 = a.str_.size(); 49 | int size2 = b.str_.size(); 50 | 51 | int max_size = (size1 > size2 ? size1 : size2); 52 | 53 | int carry = 0; 54 | 55 | int pos = 0; 56 | 57 | for (int i = 0; i < max_size; i++) { 58 | int sum = a.getDigit(i) + b.getDigit(i) + carry; 59 | 60 | c.setDigit(sum % 10, pos++); 61 | 62 | carry = (sum >= 10); 63 | } 64 | 65 | if (carry > 0) 66 | c.setDigit(carry, pos); 67 | 68 | return c; 69 | } 70 | 71 | CBigInt 72 | operator-(const CBigInt &a, const CBigInt &b) 73 | { 74 | if (a.isNaN() || b.isNaN()) 75 | return CBigInt::NaN(); 76 | 77 | if (a.isNegative() || b.isNegative()) { 78 | if (! a.isNegative()) 79 | return ( a + (-b)); 80 | else if (! b.isNegative()) 81 | return -((-a) + b ); 82 | else 83 | return -((-a) - (-b)); 84 | } 85 | 86 | if (a < b) 87 | return -(b - a); 88 | 89 | if (a.is_value_ || b.is_value_) { 90 | if (! a.is_value_) { 91 | CBigInt b1 = b; 92 | 93 | return a - b1.convString(); 94 | } 95 | else if (! b.is_value_) { 96 | CBigInt a1 = a; 97 | 98 | return a1.convString() - b; 99 | } 100 | else { 101 | ulong value1 = a.value_ - b.value_; 102 | 103 | if (value1 > std::max(a.value_, b.value_) || ((long) value1) < 0) { 104 | CBigInt a1 = a; 105 | CBigInt b1 = b; 106 | 107 | return a1.convString() - b1.convString(); 108 | } 109 | 110 | return CBigInt(value1); 111 | } 112 | } 113 | 114 | CBigInt c; 115 | 116 | c.str_ = "0"; 117 | c.is_value_ = false; 118 | 119 | int size1 = a.str_.size(); 120 | 121 | int carry = 0; 122 | 123 | int pos = 0; 124 | 125 | int i = 0; 126 | 127 | while (i < size1) { 128 | int diff = a.getDigit(i) - b.getDigit(i) + carry; 129 | 130 | if (diff < 0) { 131 | carry = -1; 132 | 133 | diff += 10; 134 | } 135 | 136 | c.setDigit(diff % 10, pos++); 137 | 138 | i++; 139 | } 140 | 141 | c.stripLeadingZeros(); 142 | 143 | return c; 144 | } 145 | 146 | CBigInt 147 | operator*(const CBigInt &a, const CBigInt &b) 148 | { 149 | if (a.isNaN() || b.isNaN()) 150 | return CBigInt::NaN(); 151 | 152 | if (a.isNegative() || b.isNegative()) { 153 | if (! a.isNegative()) 154 | return -( a * (-b)); 155 | else if (! b.isNegative()) 156 | return -((-a) * b ); 157 | else 158 | return ((-a) * (-b)); 159 | } 160 | 161 | if (a.is_value_ || b.is_value_) { 162 | if (! a.is_value_) { 163 | CBigInt b1 = b; 164 | 165 | return a * b1.convString(); 166 | } 167 | else if (! b.is_value_) { 168 | CBigInt a1 = a; 169 | 170 | return a1.convString() * b; 171 | } 172 | else { 173 | ulong value1 = a.value_ * b.value_; 174 | 175 | if (value1 < std::max(a.value_, b.value_) || ((long) value1) < 0) { 176 | CBigInt a1 = a; 177 | CBigInt b1 = b; 178 | 179 | return a1.convString() * b1.convString(); 180 | } 181 | 182 | return CBigInt(value1); 183 | } 184 | } 185 | 186 | CBigInt c; 187 | 188 | int size2 = b.str_.size(); 189 | 190 | for (int i = 0; i < size2; i++) { 191 | CBigInt c1 = a.multiplyByDigit(b.getDigit(i)); 192 | 193 | c1.shiftLeft(i); 194 | 195 | c += c1; 196 | } 197 | 198 | return c; 199 | } 200 | 201 | CBigInt 202 | CBigInt:: 203 | multiplyByDigit(int multiplier) const 204 | { 205 | int size = str_.size(); 206 | 207 | CBigInt c; 208 | 209 | c.str_ = "0"; 210 | c.is_value_ = false; 211 | 212 | int carry = 0; 213 | 214 | int pos = 0; 215 | 216 | for (int i = 0; i < size; i++) { 217 | int product = getDigit(i)*multiplier + carry; 218 | 219 | carry = product / 10; 220 | 221 | c.setDigit(product % 10, pos++); 222 | } 223 | 224 | if (carry > 0) 225 | c.setDigit(carry, pos); 226 | 227 | return c; 228 | } 229 | 230 | CBigInt 231 | operator/(const CBigInt &a, const CBigInt &b) 232 | { 233 | if (a.isNaN() || b.isNaN()) 234 | return CBigInt::NaN(); 235 | 236 | if (b.isZero()) 237 | return CBigInt::NaN(); 238 | 239 | if (a.isNegative() || b.isNegative()) { 240 | if (! a.isNegative()) 241 | return -( a / (-b)); 242 | else if (! b.isNegative()) 243 | return -((-a) / b ); 244 | else 245 | return ((-a) / (-b)); 246 | } 247 | 248 | if (b > a) 249 | return CBigInt(0L); 250 | 251 | if (a.is_value_ || b.is_value_) { 252 | if (! a.is_value_) { 253 | CBigInt b1 = b; 254 | 255 | return a / b1.convString(); 256 | } 257 | else if (! b.is_value_) { 258 | CBigInt a1 = a; 259 | 260 | return a1.convString() / b; 261 | } 262 | else { 263 | ulong value1 = a.value_ / b.value_; 264 | 265 | if (value1 > std::max(a.value_, b.value_) || ((long) value1) < 0) { 266 | CBigInt a1 = a; 267 | CBigInt b1 = b; 268 | 269 | return a1.convString() / b1.convString(); 270 | } 271 | 272 | return CBigInt(value1); 273 | } 274 | } 275 | 276 | CBigInt c; 277 | 278 | c.str_ = "0"; 279 | c.is_value_ = false; 280 | 281 | int cpos = 0; 282 | 283 | CBigInt d; 284 | 285 | int dpos = 0; 286 | 287 | int size = a.str_.size(); 288 | 289 | for (int i = 0; i < size; i++) { 290 | if (dpos > 0) 291 | d.shiftLeft(1); 292 | 293 | d.setDigit(a.getRDigit(i), 0); 294 | 295 | dpos++; 296 | 297 | if (d < b) 298 | continue; 299 | 300 | int count = 0; 301 | 302 | while (d >= b) { 303 | d -= b; 304 | 305 | count++; 306 | } 307 | 308 | if (d.isZero()) 309 | dpos = 0; 310 | 311 | if (cpos > 0) 312 | c.shiftLeft(1); 313 | 314 | c.setDigit(count, 0); 315 | 316 | cpos++; 317 | } 318 | 319 | return c; 320 | } 321 | 322 | CBigInt 323 | operator%(const CBigInt &a, const CBigInt &b) 324 | { 325 | if (a.isNaN() || b.isNaN()) 326 | return CBigInt::NaN(); 327 | 328 | if (b.isZero()) 329 | return CBigInt::NaN(); 330 | 331 | if (a.isNegative() || b.isNegative()) { 332 | if (! a.isNegative()) 333 | return a % (-b); 334 | else if (! b.isNegative()) 335 | return (-a) % b ; 336 | else 337 | return (-a) % (-b); 338 | } 339 | 340 | if (b > a) 341 | return a; 342 | 343 | if (a.is_value_ || b.is_value_) { 344 | if (! a.is_value_) { 345 | CBigInt b1 = b; 346 | 347 | return a % b1.convString(); 348 | } 349 | else if (! b.is_value_) { 350 | CBigInt a1 = a; 351 | 352 | return a1.convString() % b; 353 | } 354 | else { 355 | ulong value1 = a.value_ % b.value_; 356 | 357 | if (value1 > std::max(a.value_, b.value_) || ((long) value1) < 0) { 358 | CBigInt a1 = a; 359 | CBigInt b1 = b; 360 | 361 | return a1.convString() % b1.convString(); 362 | } 363 | 364 | return CBigInt(value1); 365 | } 366 | } 367 | 368 | CBigInt c; 369 | 370 | int cpos = 0; 371 | 372 | int size = a.str_.size(); 373 | 374 | for (int i = 0; i < size; i++) { 375 | if (cpos > 0) 376 | c.shiftLeft(1); 377 | 378 | c.setDigit(a.getRDigit(i), 0); 379 | 380 | cpos++; 381 | 382 | if (c < b) 383 | continue; 384 | 385 | int count = 0; 386 | 387 | while (c >= b) { 388 | c -= b; 389 | 390 | count++; 391 | } 392 | 393 | if (c.isZero()) 394 | cpos = 0; 395 | } 396 | 397 | return c; 398 | } 399 | 400 | bool 401 | operator<(const CBigInt &a, const CBigInt &b) 402 | { 403 | if (a.isNaN() || b.isNaN()) { 404 | if (! a.isNaN()) 405 | return false; 406 | else if (! b.isNaN()) 407 | return true; 408 | else 409 | return false; 410 | } 411 | 412 | if (a.isNegative() || b.isNegative()) { 413 | if (! a.isNegative()) 414 | return false; 415 | else if (! b.isNegative()) 416 | return true; 417 | else 418 | return ((-a) > (-b)); 419 | } 420 | 421 | if (a.is_value_ || b.is_value_) { 422 | if (! a.is_value_) { 423 | CBigInt b1 = b; 424 | 425 | return a < b1.convString(); 426 | } 427 | else if (! b.is_value_) { 428 | CBigInt a1 = a; 429 | 430 | return a1.convString() < b; 431 | } 432 | else 433 | return a.value_ < b.value_; 434 | } 435 | 436 | int size1 = a.str_.size(); 437 | int size2 = b.str_.size(); 438 | 439 | if (size1 != size2) 440 | return size1 < size2; 441 | 442 | return (a.str_ < b.str_); 443 | } 444 | 445 | bool 446 | operator>(const CBigInt &a, const CBigInt &b) 447 | { 448 | if (a.isNaN() || b.isNaN()) { 449 | if (! a.isNaN()) 450 | return true; 451 | else if (! b.isNaN()) 452 | return false; 453 | else 454 | return false; 455 | } 456 | 457 | if (a.isNegative() || b.isNegative()) { 458 | if (! a.isNegative()) 459 | return true; 460 | else if (! b.isNegative()) 461 | return false; 462 | else 463 | return ((-a) < (-b)); 464 | } 465 | 466 | if (a.is_value_ || b.is_value_) { 467 | if (! a.is_value_) { 468 | CBigInt b1 = b; 469 | 470 | return a > b1.convString(); 471 | } 472 | else if (! b.is_value_) { 473 | CBigInt a1 = a; 474 | 475 | return a1.convString() > b; 476 | } 477 | else 478 | return a.value_ > b.value_; 479 | } 480 | 481 | int size1 = a.str_.size(); 482 | int size2 = b.str_.size(); 483 | 484 | if (size1 != size2) 485 | return size1 > size2; 486 | 487 | return (a.str_ > b.str_); 488 | } 489 | 490 | bool 491 | operator<=(const CBigInt &a, const CBigInt &b) 492 | { 493 | return ! (a > b); 494 | } 495 | 496 | bool 497 | operator>=(const CBigInt &a, const CBigInt &b) 498 | { 499 | return ! (a < b); 500 | } 501 | 502 | bool 503 | operator==(const CBigInt &a, const CBigInt &b) 504 | { 505 | if (a.isNaN() || b.isNaN()) 506 | return a.isNaN() && b.isNaN(); 507 | 508 | if (a.isZero() && b.isZero()) 509 | return true; 510 | 511 | if (a.is_negative_ != b.is_negative_) 512 | return false; 513 | 514 | if (a.is_value_ || b.is_value_) { 515 | if (! a.is_value_) { 516 | CBigInt b1 = b; 517 | 518 | return a == b1.convString(); 519 | } 520 | else if (! b.is_value_) { 521 | CBigInt a1 = a; 522 | 523 | return a1.convString() == b; 524 | } 525 | else 526 | return a.value_ == b.value_; 527 | } 528 | 529 | int size1 = a.str_.size(); 530 | int size2 = b.str_.size(); 531 | 532 | if (size1 != size2) 533 | return false; 534 | 535 | return (a.str_ == b.str_); 536 | } 537 | 538 | bool 539 | operator!=(const CBigInt &a, const CBigInt &b) 540 | { 541 | return ! (a == b); 542 | } 543 | 544 | CBigInt 545 | CBigInt:: 546 | power(const CBigInt &b) const 547 | { 548 | if (isNaN() || b.isNaN()) 549 | return CBigInt::NaN(); 550 | 551 | CBigInt c; 552 | 553 | CBigInt i; 554 | 555 | c = 1; 556 | 557 | while (i < b) { 558 | c = c*(*this); 559 | 560 | i++; 561 | } 562 | 563 | return c; 564 | } 565 | 566 | CBigInt 567 | CBigInt:: 568 | factorial() const 569 | { 570 | if (isNaN()) 571 | return CBigInt::NaN(); 572 | 573 | if (*this < 0L) 574 | return CBigInt::NaN(); 575 | 576 | if (*this == 0L || *this == 1L) 577 | return *this; 578 | 579 | CBigInt a = *this - 1L; 580 | 581 | return (*this)*a.factorial(); 582 | } 583 | -------------------------------------------------------------------------------- /cppbigint/CBigInt.h: -------------------------------------------------------------------------------- 1 | #ifndef CBIGINT_H 2 | #define CBIGINT_H 3 | 4 | #include "CStrUtil.h" 5 | #include 6 | #include 7 | 8 | //https://github.com/colinw7/CBigInt 9 | class CBigInt { 10 | public: 11 | CBigInt(long value=0) { 12 | init(value); 13 | } 14 | 15 | CBigInt(const std::string &str) { 16 | init(str); 17 | } 18 | 19 | CBigInt(const char *str) { 20 | init(str); 21 | } 22 | 23 | CBigInt(const CBigInt &a) : 24 | is_nan_(a.is_nan_), is_negative_(a.is_negative_), is_value_(a.is_value_), 25 | value_(a.value_), str_(a.str_) { 26 | } 27 | 28 | friend CBigInt operator+(const CBigInt &a, const CBigInt &b); 29 | friend CBigInt operator-(const CBigInt &a, const CBigInt &b); 30 | friend CBigInt operator*(const CBigInt &a, const CBigInt &b); 31 | friend CBigInt operator/(const CBigInt &a, const CBigInt &b); 32 | friend CBigInt operator%(const CBigInt &a, const CBigInt &b); 33 | 34 | friend bool operator< (const CBigInt &a, const CBigInt &b); 35 | friend bool operator> (const CBigInt &a, const CBigInt &b); 36 | friend bool operator<=(const CBigInt &a, const CBigInt &b); 37 | friend bool operator>=(const CBigInt &a, const CBigInt &b); 38 | friend bool operator==(const CBigInt &a, const CBigInt &b); 39 | friend bool operator!=(const CBigInt &a, const CBigInt &b); 40 | 41 | friend CBigInt &operator+=(CBigInt &a, const CBigInt &b) { 42 | a = a + b; 43 | 44 | return a; 45 | } 46 | 47 | friend CBigInt &operator-=(CBigInt &a, const CBigInt &b) { 48 | a = a - b; 49 | 50 | return a; 51 | } 52 | 53 | friend CBigInt &operator*=(CBigInt &a, const CBigInt &b) { 54 | a = a * b; 55 | 56 | return a; 57 | } 58 | 59 | friend CBigInt &operator/=(CBigInt &a, const CBigInt &b) { 60 | a = a / b; 61 | 62 | return a; 63 | } 64 | 65 | friend CBigInt &operator%=(CBigInt &a, const CBigInt &b) { 66 | a = a % b; 67 | 68 | return a; 69 | } 70 | 71 | const CBigInt operator-() const { 72 | if (isNaN()) 73 | return *this; 74 | 75 | CBigInt b = *this; 76 | 77 | b.negate(); 78 | 79 | return b; 80 | } 81 | 82 | const CBigInt operator+() const { 83 | return *this; 84 | } 85 | 86 | CBigInt &operator=(const CBigInt &b) { 87 | if (this == &b) 88 | return *this; 89 | 90 | is_nan_ = b.is_nan_; 91 | is_negative_ = b.is_negative_; 92 | is_value_ = b.is_value_; 93 | value_ = b.value_; 94 | str_ = b.str_; 95 | 96 | return *this; 97 | } 98 | 99 | const CBigInt operator++() { 100 | if (isNaN()) 101 | return *this; 102 | 103 | *this = *this + 1; 104 | 105 | return *this; 106 | } 107 | 108 | const CBigInt operator++(int) { 109 | if (isNaN()) 110 | return *this; 111 | 112 | CBigInt t = *this; 113 | 114 | *this = *this + 1; 115 | 116 | return t; 117 | } 118 | 119 | const CBigInt operator--() { 120 | if (isNaN()) 121 | return *this; 122 | 123 | *this = *this - 1; 124 | 125 | return *this; 126 | } 127 | 128 | const CBigInt operator--(int) { 129 | if (isNaN()) 130 | return *this; 131 | 132 | CBigInt t = *this; 133 | 134 | *this = *this - 1; 135 | 136 | return t; 137 | } 138 | 139 | CBigInt power(const CBigInt &b) const; 140 | 141 | CBigInt factorial() const; 142 | 143 | bool isZero() const { 144 | if (isNaN()) 145 | return false; 146 | 147 | if (is_value_) 148 | return (value_ == 0); 149 | else 150 | return (str_ == "0"); 151 | } 152 | 153 | bool isOne() const { 154 | if (isNaN()) 155 | return false; 156 | 157 | if (is_value_) 158 | return (value_ == 1); 159 | else 160 | return (str_ == "1"); 161 | } 162 | 163 | bool isOdd() const { 164 | if (isNaN()) 165 | return true; 166 | 167 | if (is_value_) 168 | return (value_ & 1); 169 | else 170 | return (str_[0] == '1' || str_[0] == '3' || 171 | str_[0] == '5' || str_[0] == '7' || str_[0] == '9'); 172 | } 173 | 174 | bool isEven() const { 175 | return ! isOdd(); 176 | } 177 | 178 | void negate() { 179 | is_negative_ = ! is_negative_; 180 | } 181 | 182 | bool isNegative() const { 183 | if (isNaN()) 184 | return false; 185 | 186 | return is_negative_; 187 | } 188 | 189 | bool isPositive() const { 190 | return ! isNegative(); 191 | } 192 | 193 | bool isNaN() const { 194 | return is_nan_; 195 | } 196 | 197 | void setNaN() { 198 | is_nan_ = true; 199 | } 200 | 201 | static CBigInt NaN() { 202 | CBigInt nan; 203 | 204 | nan.setNaN(); 205 | 206 | return nan; 207 | } 208 | 209 | void print(std::ostream &os = std::cout) const { 210 | os << toString(); 211 | } 212 | 213 | friend std::ostream &operator<<(std::ostream &os, const CBigInt &i) { 214 | i.print(os); 215 | 216 | return os; 217 | } 218 | 219 | std::string toString() const { 220 | if (isNaN()) 221 | return "NaN"; 222 | 223 | std::string str; 224 | 225 | if (isNegative()) 226 | str += "-"; 227 | 228 | if (is_value_) 229 | str += CStrUtil::toString(value_); 230 | else 231 | str += '\"' + str_ + '\"'; 232 | 233 | return str; 234 | } 235 | 236 | private: 237 | void init(long value) { 238 | is_nan_ = false; 239 | is_value_ = true; 240 | 241 | if (value < 0) { 242 | is_negative_ = true; 243 | value_ = -value; 244 | } 245 | else { 246 | is_negative_ = false; 247 | value_ = value; 248 | } 249 | } 250 | 251 | void init(const std::string &str) { 252 | is_nan_ = false; 253 | is_negative_ = false; 254 | is_value_ = false; 255 | 256 | uint len = str.size(); 257 | 258 | if (len < 1) { 259 | // CTHROW("Invalid Integer"); 260 | is_value_ = true; 261 | value_ = 0; 262 | return; 263 | } 264 | 265 | if (CStrUtil::casecmp(str, "nan") == 0) { 266 | is_nan_ = true; 267 | return; 268 | } 269 | 270 | uint start = 0; 271 | 272 | if (str[start] == '-') { 273 | is_negative_ = true; 274 | 275 | if (len < 2) { 276 | // CTHROW("Invalid Integer"); 277 | is_value_ = true; 278 | value_ = 0; 279 | return; 280 | } 281 | 282 | start++; 283 | } 284 | 285 | for (uint i = start; i < len; i++) { 286 | if (! isdigit(str[i])) { 287 | // CTHROW("Invalid Integer"); 288 | is_value_ = true; 289 | value_ = 0; 290 | return; 291 | } 292 | } 293 | 294 | str_ = str.substr(start); 295 | 296 | stripLeadingZeros(); 297 | 298 | if (isZero()) 299 | is_negative_ = false; 300 | 301 | if (CStrUtil::isInteger(str_)) { 302 | long value1; 303 | 304 | is_value_ = true; 305 | 306 | CStrUtil::toInteger(str_, &value1); 307 | 308 | value_ = value1; 309 | } 310 | } 311 | 312 | CBigInt &convString() { 313 | if (! is_value_) 314 | return *this; 315 | 316 | is_value_ = false; 317 | 318 | str_ = CStrUtil::toString(value_); 319 | 320 | return *this; 321 | } 322 | 323 | CBigInt multiplyByDigit(int multiplier) const; 324 | 325 | void setDigit(int digit, int pos) { 326 | char c = (digit + '0'); 327 | 328 | while (pos >= (int) str_.size()) 329 | str_ = "0" + str_; 330 | 331 | str_[str_.size() - pos - 1] = c; 332 | } 333 | 334 | int getDigit(int pos) const { 335 | if (pos < 0 || pos >= (int) str_.size()) 336 | return 0; 337 | 338 | return (int) (str_[str_.size() - pos - 1] - '0'); 339 | } 340 | 341 | int getRDigit(int pos) const { 342 | if (pos < 0 || pos >= (int) str_.size()) 343 | return 0; 344 | 345 | return (int) (str_[pos] - '0'); 346 | } 347 | 348 | void shiftLeft(int num) { 349 | for (int i = 0; i < num; i++) 350 | str_ += "0"; 351 | } 352 | 353 | void stripLeadingZeros() { 354 | while (str_.size() > 1 && str_[0] == '0') { 355 | str_ = str_.substr(1); 356 | } 357 | } 358 | 359 | private: 360 | bool is_nan_ { false }; 361 | bool is_negative_ { false }; 362 | bool is_value_ { false }; 363 | ulong value_ { 0 }; 364 | std::string str_; 365 | }; 366 | 367 | namespace CBigIntC { 368 | static CBigInt Zero { 0L }; 369 | static CBigInt One { 1L }; 370 | } 371 | 372 | #endif 373 | -------------------------------------------------------------------------------- /cppbigint/CBigIntFib.cpp: -------------------------------------------------------------------------------- 1 | #include "CBigInt.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | typedef unsigned long IResult; 8 | typedef std::map IMap; 9 | typedef std::map BigMap; 10 | 11 | IMap fibICache; 12 | BigMap fibBigCache; 13 | 14 | IResult fib(int n) { 15 | if (n <= 0) return 0; 16 | if (n <= 1) return 1; 17 | 18 | auto p = fibICache.find(n); 19 | 20 | if (p == fibICache.end()) { 21 | IResult res = fib(n - 2) + fib(n - 1); 22 | 23 | p = fibICache.insert(p, IMap::value_type(n, res)); 24 | } 25 | 26 | return (*p).second; 27 | } 28 | 29 | CBigInt fibBig(int n) { 30 | if (n <= 0) return CBigIntC::Zero; 31 | if (n <= 1) return CBigIntC::One; 32 | 33 | auto p = fibBigCache.find(n); 34 | 35 | if (p == fibBigCache.end()) { 36 | CBigInt res = fibBig(n - 2) + fibBig(n - 1); 37 | 38 | p = fibBigCache.insert(p, BigMap::value_type(n, res)); 39 | } 40 | 41 | return (*p).second; 42 | } 43 | 44 | int 45 | main(int argc, char **argv) 46 | { 47 | if (argc <= 1) 48 | exit(1); 49 | 50 | int n = atoi(argv[1]); 51 | 52 | std::cerr << fib(n) << std::endl; 53 | 54 | std::cerr << fibBig(n) << std::endl; 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /cppbigint/CBigIntTest.cpp: -------------------------------------------------------------------------------- 1 | #include "CBigInt.h" 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | //https://github.com/colinw7/CBigInt 7 | int main(int argc, char **argv) 8 | { 9 | if (argc != 3) { 10 | std::cerr << "Usage: CBigIntTest a b" << std::endl; 11 | exit(1); 12 | } 13 | 14 | CBigInt a(argv[1]); 15 | CBigInt b(argv[2]); 16 | 17 | CBigInt c = a + b; 18 | CBigInt d = a - b; 19 | CBigInt e = a * b; 20 | CBigInt f = a / b; 21 | CBigInt g = a % b; 22 | 23 | cout << a << " + " << b << " = " << c << endl; 24 | cout << a << " - " << b << " = " << d << endl; 25 | cout << a << " * " << b << " = " << e << endl; 26 | cout << a << " / " << b << " = " << f << endl; 27 | cout << a << " % " << b << " = " << g << endl; 28 | 29 | cout << a << " > " << b << " = " << (a > b) << endl; 30 | cout << a << " < " << b << " = " << (a < b) << endl; 31 | cout << a << " >= " << b << " = " << (a >= b) << endl; 32 | cout << a << " <= " << b << " = " << (a <= b) << endl; 33 | cout << a << " == " << b << " = " << (a == b) << endl; 34 | 35 | CBigInt p1 = 2; 36 | CBigInt p2 = 64; 37 | 38 | CBigInt pp = p1.power(p2); 39 | 40 | cout << p1 << " ** " << p2 << " = " << pp << endl; 41 | 42 | CBigInt fi = 50; 43 | 44 | CBigInt fo = fi.factorial(); 45 | 46 | cout << fi << "! = " << fo << endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /cppbigint/CStrUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef CSTRUTIL_H 2 | #define CSTRUTIL_H 3 | 4 | #define _CRT_SECURE_NO_DEPRECATE 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | //#define uint unsigned int 11 | //#define ulong unsigned long 12 | 13 | typedef unsigned int uint; 14 | typedef unsigned long ulong; 15 | 16 | class CRegExp; 17 | 18 | enum CPrintFFlags { 19 | CPRINTF_LEFT_JUSTIFY = (1<<0), 20 | CPRINTF_DISPLAY_SIGN = (1<<1), 21 | CPRINTF_PAD_POSITIVE = (1<<2), 22 | CPRINTF_USE_ALTERNATE = (1<<3), 23 | CPRINTF_ZERO_PAD = (1<<4), 24 | CPRINTF_FIELD_WIDTH_AS_VALUE = (1<<5), 25 | CPRINTF_PRECISION_AS_VALUE = (1<<6) 26 | }; 27 | 28 | class CStrCmp; 29 | class CStrWord; 30 | class CStrWords; 31 | 32 | class CStrCmpFunctor { 33 | public: 34 | int operator()(const std::string &str1, const std::string &str2) { 35 | return str1 < str2; 36 | } 37 | }; 38 | 39 | class CWordDef { 40 | protected: 41 | int group_char; 42 | char escape_char_; 43 | bool allow_escapes_; 44 | 45 | public: 46 | CWordDef() : 47 | group_char(0), escape_char_('\\'), allow_escapes_(true) { 48 | } 49 | 50 | virtual ~CWordDef() { } 51 | 52 | bool getEscapeChar () const { return escape_char_ ; } 53 | bool getAllowEscapes() const { return allow_escapes_; } 54 | 55 | virtual bool isWordChar(char c) const; 56 | virtual bool isSpace(char c) const; 57 | virtual bool isStartGroup(char c) const; 58 | virtual bool isEndGroup(char c) const; 59 | 60 | bool isStartGroupI(char c) const; 61 | bool isEndGroupI (char c) const; 62 | }; 63 | 64 | namespace CStrUtil { 65 | std::string toString(const char *str); 66 | std::string toString(const std::string &str); 67 | 68 | std::string toString(char c); 69 | std::string toString(bool flag); 70 | std::string toString(int integer); 71 | std::string toString(uint integer); 72 | std::string toString(long integer); 73 | std::string toString(ulong integer); 74 | std::string toString(double real); 75 | std::string toString(const std::vector &words, 76 | const std::string &sep=""); 77 | std::string toString(const std::vector &words, 78 | int start, int end=-1, const std::string &sep=""); 79 | std::string toString(const char **words, uint num_words, 80 | int start, int end=-1, const std::string &sep=""); 81 | std::string toString(const char **words, uint num_words, 82 | const std::string &sep=""); 83 | std::string toString(std::vector::const_iterator pstr1, 84 | std::vector::const_iterator pstr2, 85 | const std::string &sep=""); 86 | std::string toString(const CStrWords &words, const std::string &sep=""); 87 | 88 | bool decodeHexString(const std::string &str, uint *value); 89 | bool decodeHexChar(unsigned char c, uint *value); 90 | 91 | void setHexUpper(bool upper); 92 | 93 | std::string toHexString(uint integer, uint width=4); 94 | std::string toHexString(signed int integer, uint width=4); 95 | 96 | std::string toOctString(int integer); 97 | std::string toOctStringInWidth(int integer, uint width=4); 98 | 99 | std::string toBitString(int c); 100 | 101 | bool isBool(const std::string &str); 102 | bool toBool(const std::string &str); 103 | bool toBool(const std::string &str, bool *value); 104 | 105 | bool isBaseInteger(const std::string &str, uint base); 106 | long toBaseInteger(const std::string &str, uint base); 107 | bool toBaseInteger(const std::string &str, uint base, int *integer); 108 | bool toBaseInteger(const std::string &str, uint base, uint *integer); 109 | bool toBaseInteger(const std::string &str, uint base, long *integer); 110 | 111 | bool isInteger(const std::string &str); 112 | long toInteger(const std::string &str); 113 | bool toInteger(const std::string &str, short *integer); 114 | bool toInteger(const std::string &str, int *integer); 115 | bool toInteger(const std::string &str, uint *integer); 116 | bool toInteger(const std::string &str, long *integer); 117 | 118 | bool isReal(const std::string &str); 119 | double toReal(const std::string &str); 120 | bool toReal(const std::string &str, double *real); 121 | 122 | bool isBaseChar(int c, uint base, int *value = NULL); 123 | 124 | bool isCComment(const std::string &str, uint pos); 125 | bool readCComment(const std::string &str, uint *pos, 126 | bool *in_comment, std::string &comment); 127 | 128 | bool isCNumber(const std::string &str, uint pos); 129 | bool readCNumber(const std::string &str, uint *pos, std::string &number); 130 | 131 | bool isCCharacter(const std::string &str, uint pos); 132 | bool readCCharacter(const std::string &str, uint *pos, std::string &number); 133 | 134 | bool isCString(const std::string &str, uint pos); 135 | bool readCString(const std::string &str, uint *pos, std::string &number); 136 | 137 | std::string stripSpaces(const std::string &str, 138 | bool front=true, bool back=true); 139 | 140 | char *stripSpaces(char *str, bool front=true, bool back=true); 141 | 142 | const char *stripSpaces(const char *str, bool front=true, bool back=true); 143 | 144 | std::string compressSpaces(const std::string &str); 145 | 146 | std::string toUpper(const std::string &str); 147 | char *toUpper(char *str); 148 | const char *toUpper(const char *str); 149 | std::string toLower(const std::string &str); 150 | char *toLower(char *str); 151 | const char *toLower(const char *str); 152 | 153 | std::string capitalize(const std::string &str); 154 | 155 | #if 0 156 | int gregsub(const std::string &istr, const CRegExp &pattern, 157 | const std::string &rstr, std::string &ostr); 158 | bool regsub(const std::string &istr, const CRegExp &pattern, 159 | const std::string &rstr, std::string &ostr); 160 | #endif 161 | 162 | std::string replace(const std::string &str, const std::string &old_str, 163 | const std::string &new_str); 164 | 165 | std::string translate(const std::string &str, 166 | const std::string &old_chars, 167 | const std::string &new_chars, bool remove=false); 168 | 169 | void addFields(const std::string &str, std::vector &words, 170 | const std::string &splitters="", bool skipEmpty=false); 171 | bool skipSpace(const char *str, uint *pos); 172 | bool skipSpace(const char **str); 173 | bool skipSpace(char **str); 174 | bool skipSpace(const std::string &str, int *pos); 175 | bool skipSpace(const std::string &str, uint *pos); 176 | 177 | bool skipNonSpace(const char *str, uint *pos); 178 | bool skipNonSpace(const char **str); 179 | bool skipNonSpace(char **str); 180 | bool skipNonSpace(const std::string &str, int *pos); 181 | bool skipNonSpace(const std::string &str, uint *pos); 182 | 183 | bool skipDoubleQuotedString(const std::string &str, uint *pos); 184 | bool skipSingleQuotedString(const std::string &str, uint *pos); 185 | bool skipBackQuotedString (const std::string &str, uint *pos); 186 | 187 | bool readInteger(const std::string &str, uint *pos, int *integer); 188 | bool readInteger(const char *str, uint *pos, int *integer); 189 | 190 | bool readBaseInteger(const std::string &str, uint base, 191 | uint *pos, int *integer); 192 | bool readBaseInteger(const char *str, uint base, 193 | uint *pos, int *integer); 194 | 195 | bool skipInteger(const std::string &str, uint *pos); 196 | bool skipInteger(const char *str, uint *pos); 197 | 198 | bool skipBaseInteger(const std::string &str, uint base, uint *pos); 199 | bool skipBaseInteger(const char *str, uint base, uint *pos); 200 | 201 | bool readReal(const std::string &str, uint *pos, double *real); 202 | bool readReal(const char *str, uint *pos, double *real); 203 | 204 | bool readNumber(const std::string &str, uint *pos, double &real, int &integer, bool &is_real); 205 | 206 | void fput(const std::string &str, FILE *fp); 207 | 208 | bool isIdentifier(const std::string &str); 209 | bool isIdentifier(const std::string &str, uint pos); 210 | bool readIdentifier(const std::string &str, uint *pos, 211 | std::string &identifier); 212 | bool skipIdentifier(const std::string &str, uint *pos); 213 | 214 | bool isCIdentifier(const std::string &str, uint pos); 215 | bool readCIdentifier(const std::string &str, uint *pos, 216 | std::string &identifier); 217 | 218 | bool isCOperator(const std::string &str, uint pos); 219 | bool readCOperator(const std::string &str, uint *pos, std::string &opstr); 220 | bool isCOperatorChar(char c); 221 | 222 | bool isCSeparator(const std::string &str, uint pos); 223 | bool readCSeparator(const std::string &str, uint *pos, std::string &opstr); 224 | bool isCSeparatorChar(char c); 225 | 226 | bool replaceCTriGraphs(std::string &str); 227 | 228 | bool readNonSpace(const std::string &str, uint *pos, std::string &word); 229 | 230 | std::string replaceEscapeCodes(const std::string &str); 231 | 232 | std::string addEscapeChars(const std::string &str, const std::string &chars); 233 | std::string removeEscapeChars(const std::string &str); 234 | 235 | bool encodeEscapeChar(const std::string &str, char *c); 236 | 237 | std::string encodeCharString(char c); 238 | 239 | std::string insertEscapeCodes(const std::string &str); 240 | 241 | void sort(std::vector &strs); 242 | void uniq(const std::vector &strs, 243 | std::vector &uniq_strs); 244 | 245 | std::string mostMatch(const std::vector &strs); 246 | 247 | void print(std::ostream &os, const std::vector &strs); 248 | 249 | void printf(const char *format, ...); 250 | void eprintf(const char *format, ...); 251 | void fprintf(std::ostream &os, const char *format, ...); 252 | void sprintf(std::string &str, const char *format, ...); 253 | std::string strprintf(const std::string *format, ...); 254 | std::string strprintf(const char *format, ...); 255 | 256 | void vprintf(const char *format, va_list *vargs); 257 | void veprintf(const char *format, va_list *vargs); 258 | void vfprintf(std::ostream &os, const char *format, va_list *vargs); 259 | void vsprintf(std::string &str, const char *format, va_list *vargs); 260 | std::string vstrprintf(const char *format, va_list *vargs); 261 | 262 | bool readFormat(const std::string &str, uint *pos, std::string &format, 263 | int *field_width, int *precision, 264 | char *length_modifier, char *format_code, int *flags); 265 | bool readRealFormat(const std::string &str, uint *pos, std::string &format); 266 | bool readIntegerFormat(const std::string &str, uint *pos, 267 | std::string &format); 268 | bool readStringFormat(const std::string &str, uint *pos, 269 | std::string &format); 270 | 271 | char *strdup(const char *str); 272 | char *strdup(const std::string &str); 273 | char *strndup(const char *s, uint n); 274 | 275 | char *strstr(const char *str1, const char *str2); 276 | char *strstr(const char *p1, const char *p2, const char *str2, int len=-1); 277 | 278 | char *strrstr(const char *str1, const char *str2); 279 | char *strrstr(const char *p1, const char *p2, const char *str2, int len=-1); 280 | 281 | char *strchr(const char *str, char c); 282 | char *strchr(const char *p1, const char *p2, char c); 283 | 284 | char *strrchr(const char *str, char c); 285 | char *strrchr(const char *p1, const char *p2, char c); 286 | 287 | void addLines(const std::string &str, std::vector &lines); 288 | 289 | std::string readLine(const std::string &str, std::string &line); 290 | 291 | int cmp(const std::string &str1, const std::string &str2); 292 | 293 | int casecmp(const std::string &str1, const std::string &str2); 294 | 295 | std::string::size_type casefind(const std::string &str1, const std::string &str2); 296 | 297 | bool equal(char *str1, char *str2); 298 | 299 | std::string concatFileNames(const std::string &lhs, 300 | const std::string &rhs); 301 | 302 | uint maxLen(std::vector &words); 303 | 304 | std::string duplicate(const std::string &str, uint n); 305 | 306 | std::string single_quote(const std::string &str); 307 | std::string double_quote(const std::string &str); 308 | std::string back_quote(const std::string &str); 309 | 310 | std::string charsToString(int c, ...); 311 | 312 | void stringExpand(const std::string &str, std::vector &ostrs); 313 | 314 | void stringExpand1(const std::vector &istrs, 315 | std::vector &ostrs); 316 | void stringExpand2(const std::string &lhs, const std::string &rhs, 317 | const std::string &chars, 318 | std::vector &strs); 319 | 320 | std::string caseSepToUnderscoreSep(const std::string &str); 321 | std::string underscoreSepToCaseSep(const std::string &str); 322 | 323 | typedef bool (*IsCType)(int c); 324 | 325 | IsCType getIsCType(const std::string &is_type); 326 | 327 | bool isalnum (int c); 328 | bool isalpha (int c); 329 | bool iscntrl (int c); 330 | bool isdigit (int c); 331 | bool isgraph (int c); 332 | bool islower (int c); 333 | bool isprint (int c); 334 | bool ispunct (int c); 335 | bool isspace (int c); 336 | bool isupper (int c); 337 | bool isxdigit(int c); 338 | bool isodigit(int c); 339 | 340 | std::string toEnglish(uint i); 341 | 342 | void permute(const std::string &word, uint n); 343 | } 344 | 345 | class CStrCharPos { 346 | private: 347 | char c_; 348 | int pos_; 349 | 350 | public: 351 | CStrCharPos(char c, int pos) : c_(c), pos_(pos) { } 352 | 353 | char getChar() const { return c_; } 354 | int getPos () const { return pos_; } 355 | 356 | void shift(int delta) { pos_ += delta; } 357 | }; 358 | 359 | class CStrWord { 360 | private: 361 | typedef std::vector PosList; 362 | 363 | std::string word_; 364 | int pos_; 365 | char start_group_; 366 | char end_group_; 367 | PosList escape_chars_; 368 | 369 | public: 370 | CStrWord(const std::string &word=std::string(""), int pos=0) : 371 | word_(word), pos_(pos), start_group_('\0'), end_group_('\0'), escape_chars_() { 372 | } 373 | 374 | const std::string &getWord() const { return word_; } 375 | 376 | int getStartPos() const { return pos_; } 377 | int getEndPos () const { return pos_ + word_.size() - 1; } 378 | 379 | char getStartGroup() const { return start_group_; } 380 | char getEndGroup () const { return end_group_ ; } 381 | 382 | int getNumEscapeChars() const { return escape_chars_.size(); } 383 | 384 | const CStrCharPos &getEscapeChar(int i) const { return escape_chars_[i]; } 385 | 386 | long toInteger() const; 387 | double toReal () const; 388 | 389 | int size() const { return word_.size(); } 390 | 391 | const char *c_str() const { return word_.c_str(); } 392 | 393 | void truncate(int start, int end) { 394 | std::vector escape_chars1; 395 | 396 | for (uint i = 0; i < escape_chars_.size(); i++) { 397 | if (escape_chars_[i].getPos() >= start || 398 | escape_chars_[i].getPos() <= end) { 399 | escape_chars_[i].shift(-start); 400 | 401 | escape_chars1.push_back(escape_chars_[i]); 402 | } 403 | } 404 | 405 | escape_chars_ = escape_chars1; 406 | 407 | word_ = word_.substr(start, end - start + 1); 408 | } 409 | 410 | void shift(int delta) { 411 | pos_ += delta; 412 | 413 | for (uint i = 0; i < escape_chars_.size(); i++) 414 | escape_chars_[i].shift(delta); 415 | } 416 | 417 | int operator==(const std::string &str) const { return word_ == str; } 418 | int operator==(const char *str) const { return word_ == str; } 419 | 420 | void setStartGroup(char c) { start_group_ = c; } 421 | void setEndGroup (char c) { end_group_ = c; } 422 | 423 | void addEscapeChar(char c, int pos) { 424 | escape_chars_.push_back(CStrCharPos(c, pos)); 425 | } 426 | 427 | void setWord(const std::string &word, int pos) { 428 | word_ = word; 429 | pos_ = pos; 430 | } 431 | }; 432 | 433 | class CStrWords { 434 | private: 435 | std::string str_; 436 | std::vector word_datas_; 437 | 438 | public: 439 | typedef std::vector::iterator iterator; 440 | typedef std::vector::const_iterator const_iterator; 441 | 442 | CStrWords(const std::string &str) : str_(str), word_datas_() { } 443 | 444 | ~CStrWords() { } 445 | 446 | int size() const { return word_datas_.size(); } 447 | 448 | void addWord(const std::string &word, int start_pos) { 449 | CStrWord word_data(word, start_pos); 450 | 451 | word_datas_.push_back(word_data); 452 | } 453 | 454 | void addWord(const CStrWord &word) { 455 | word_datas_.push_back(word); 456 | } 457 | 458 | const CStrWord &getWord(int pos) const { 459 | if (pos < 0 || pos > size()) 460 | throw "Invalid Subscript"; 461 | 462 | return word_datas_[pos]; 463 | } 464 | 465 | void truncate(int start, int end); 466 | 467 | void truncateWord(int pos, int start, int end); 468 | 469 | iterator begin() { return word_datas_.begin(); } 470 | iterator end () { return word_datas_.end (); } 471 | 472 | const_iterator begin() const { return word_datas_.begin(); } 473 | const_iterator end () const { return word_datas_.end (); } 474 | 475 | const CStrWord &operator[](int pos) const { 476 | return getWord(pos); 477 | } 478 | }; 479 | 480 | #endif 481 | -------------------------------------------------------------------------------- /cppbigint/CStrUtilTest.cpp: -------------------------------------------------------------------------------- 1 | #include "CStrUtil.h" 2 | #include 3 | 4 | using std::string; 5 | using std::cout; 6 | using std::endl; 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | string istring = CStrUtil::toString(45); 12 | 13 | cout << istring << endl; 14 | 15 | string rstring = CStrUtil::toString(3.563); 16 | 17 | cout << rstring << endl; 18 | 19 | cout << CStrUtil::toInteger(istring) << endl; 20 | 21 | cout << CStrUtil::toReal(rstring) << endl; 22 | 23 | cout << "'" << CStrUtil::stripSpaces("fred") << 24 | "'" << endl; 25 | cout << "'" << CStrUtil::stripSpaces(" fred") << 26 | "'" << endl; 27 | cout << "'" << CStrUtil::stripSpaces("fred ") << 28 | "'" << endl; 29 | cout << "'" << CStrUtil::stripSpaces(" fred ") << 30 | "'" << endl; 31 | cout << "'" << CStrUtil::stripSpaces(" fred ", true, false) << 32 | "'" << endl; 33 | cout << "'" << CStrUtil::stripSpaces(" fred ", false, true) << 34 | "'" << endl; 35 | cout << "'" << CStrUtil::stripSpaces(" fred ", false, false) << 36 | "'" << endl; 37 | 38 | cout << CStrUtil::toLower ("heLLo") << endl; 39 | cout << CStrUtil::toUpper ("heLLo") << endl; 40 | cout << CStrUtil::capitalize("heLLo") << endl; 41 | 42 | cout << CStrUtil::translate("1234", "0123456789", "1234567890") << endl; 43 | cout << CStrUtil::translate("a2aa2a", "a", "", true) << endl; 44 | 45 | 46 | int n = 1; 47 | 48 | for (int i = 0; i < 10; ++i) { 49 | cout << CStrUtil::toOctStringInWidth(n, 3); 50 | 51 | n *= 2; 52 | } 53 | 54 | cout << endl; 55 | } 56 | -------------------------------------------------------------------------------- /cppbigint/CThrow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | void CTHROW(std::string msg) 6 | { 7 | std::cout << msg << std::endl; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /cpptool.cpp: -------------------------------------------------------------------------------- 1 | #include "cpptool.h" 2 | 3 | string transform(int x, int y, string s) 4 | { 5 | string res = ""; 6 | int sum = 0; 7 | for (unsigned int i = 0; i < s.length(); ++i) 8 | { 9 | if (s[i] == '-') continue; 10 | if (s[i] >= '0' && s[i] <= '9') 11 | { 12 | sum = sum*x + s[i] - '0'; 13 | } 14 | else { 15 | sum = sum*x + s[i] - 'A' + 10; 16 | 17 | } 18 | 19 | } 20 | while (sum) 21 | { 22 | char temp = sum %y; 23 | sum /= y; 24 | if (temp <= 9) 25 | { 26 | temp += '0'; 27 | } 28 | else { 29 | temp = temp - 10 + 'A'; 30 | } 31 | res = temp + res; 32 | } 33 | if (res.length() == 0) res = "0"; 34 | if (s[0] == '-') 35 | res = '-' + res; 36 | return res; 37 | } 38 | 39 | bool endWith(const char * str, const char * end) 40 | { 41 | bool result = false; 42 | if (str != NULL && end != NULL) 43 | { 44 | int l1 = strlen(str); 45 | int l2 = strlen(end); 46 | if (l1 >= l2) { 47 | if (strcmp(str + l1 - l2, end) == 0) 48 | { 49 | result = true; 50 | } 51 | } 52 | } 53 | return result; 54 | } 55 | char* boolToStr(int flag) 56 | { 57 | return flag ? "true" : "false"; 58 | } 59 | void getCurrentFileList(std::vector &filelist, char *ext) 60 | { 61 | long file; 62 | struct _finddata_t find; 63 | _chdir("."); 64 | if ((file = _findfirst("*.*", &find)) == -1L) 65 | { 66 | return ; 67 | } 68 | if (endWith(find.name, ext)) 69 | { 70 | filelist.push_back(string(find.name)); 71 | } 72 | while (_findnext(file, &find) == 0) 73 | { 74 | //printf("%s\n", find.name); 75 | if (endWith(find.name, ext)) 76 | { 77 | filelist.push_back(string(find.name)); 78 | } 79 | } 80 | _findclose(file); 81 | } 82 | -------------------------------------------------------------------------------- /cpptool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define _CRT_SECURE_NO_DEPRECATE 4 | //#include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | 18 | string transform(int x, int y, string s); 19 | bool endWith(const char * str, const char * end); 20 | void getCurrentFileList(std::vector &filelist, char *ext); 21 | char* boolToStr(int flag); 22 | -------------------------------------------------------------------------------- /cpptool_main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/cpptool_main.cpp -------------------------------------------------------------------------------- /ctool.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/ctool.c -------------------------------------------------------------------------------- /ctool.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/ctool.h -------------------------------------------------------------------------------- /ctool_main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/ctool_main.c -------------------------------------------------------------------------------- /c语言动态内存分配.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/c语言动态内存分配.c -------------------------------------------------------------------------------- /debug.c: -------------------------------------------------------------------------------- 1 | // 2 | // debug.c 3 | // 4 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 5 | // 6 | 7 | 8 | #include "debug.h" 9 | 10 | 11 | void debug(char* file,int line,DebugLevel level,char *mes,...) 12 | { 13 | 14 | char buf[256]; 15 | 16 | va_list args; 17 | va_start (args, mes); 18 | vsprintf (buf,mes, args); 19 | va_end (args); 20 | 21 | switch(level) 22 | { 23 | case Info: 24 | fprintf(stderr, "INFO: %s FILE: %s LINE: %i\n",buf,file,line); 25 | break; 26 | case Warning: 27 | fprintf(stderr, "WARNING: %s FILE: %s LINE: %i ERROR: %s\n",buf,file,line,strerror(errno)); 28 | 29 | #if defined(DEBUG) 30 | 31 | fprintf(stderr,"Continue(y/n)?\n"); 32 | while(1) 33 | { 34 | char key=getchar(); 35 | 36 | if(key=='n') 37 | { 38 | fprintf(stderr,"Will abord...\n"); 39 | exit(EXIT_FAILURE); 40 | } 41 | if(key=='y') 42 | { 43 | fprintf(stderr, "Will continue..\n"); 44 | break; 45 | } 46 | 47 | } 48 | 49 | #endif 50 | 51 | break; 52 | case Fatal: 53 | fprintf(stderr, "FATAL: %s FILE: %s LINE: %i ERROR: %s\n",buf,file,line,strerror(errno)); 54 | fprintf(stderr,"Will abord...\n"); 55 | exit(EXIT_FAILURE); 56 | break; 57 | 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /debug.h: -------------------------------------------------------------------------------- 1 | // 2 | // debug.h 3 | // glututor1 4 | // 5 | // Created by Macbook White on 11/21/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #define _CRT_SECURE_NO_DEPRECATE 10 | 11 | #ifndef DEBUG_H 12 | #define DEBUG_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | typedef enum 21 | { 22 | Info, 23 | Warning, 24 | Fatal 25 | 26 | }DebugLevel; 27 | 28 | //https://github.com/justinkadima/cLibrary/blob/master/debug.c 29 | 30 | #define __info(mes,...) debug(__FILE__,__LINE__,Info,mes,__VA_ARGS__) 31 | 32 | #define __fatal(mes,...) debug(__FILE__,__LINE__,Fatal,mes,__VA_ARGS__) 33 | 34 | #define __warn(mes,...) debug(__FILE__,__LINE__,Warning,mes,__VA_ARGS__) 35 | 36 | void debug(char* file,int line,DebugLevel level,char *mes,...); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /dynamic_array.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/dynamic_array.c -------------------------------------------------------------------------------- /dynamic_array.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/dynamic_array.cpp -------------------------------------------------------------------------------- /dynamic_array2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/dynamic_array2.cpp -------------------------------------------------------------------------------- /dynamic_array3.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/dynamic_array3.cpp -------------------------------------------------------------------------------- /log.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "log.h" 5 | 6 | struct timeval *stopwatch_time() { 7 | struct timeval *tv_time = malloc(sizeof(struct timeval)); 8 | gettimeofday(tv_time, NULL); 9 | 10 | return tv_time; 11 | } 12 | 13 | void stopwatch_stop(struct timeval *start_time) { 14 | struct timeval *end_time = stopwatch_time(); 15 | unsigned long msec; 16 | 17 | msec = (end_time->tv_sec - start_time->tv_sec) * 1000; 18 | msec += (end_time->tv_usec - start_time->tv_usec) / 1000; 19 | 20 | info("request completed in %lu ms", msec); 21 | free(start_time); 22 | free(end_time); 23 | } 24 | -------------------------------------------------------------------------------- /log.h: -------------------------------------------------------------------------------- 1 | // based on Zed Show debug macros 2 | // http://c.learncodethehardway.org/book/learn-c-the-hard-waych21.html 3 | #ifndef __dbg_h__ 4 | #define __dbg_h__ 5 | 6 | #include 7 | #include 8 | #include 9 | //#include 10 | 11 | struct timeval *stopwatch_time(); 12 | void stopwatch_stop(struct timeval *end_time); 13 | 14 | #ifdef NDEBUG 15 | #define debug(M, ...) 16 | #else 17 | #define debug(M, ...) fprintf(stderr, "[DEBUG][%d] %s:%d: " M "\n", getpid(), __FILE__, __LINE__, ##__VA_ARGS__) 18 | #endif 19 | 20 | #define err(M, ...) fprintf(stderr, "[ERROR][%d] (%s:%d) " M "\n", getpid(), __FILE__, __LINE__, ##__VA_ARGS__) 21 | #define warn(M, ...) fprintf(stderr, "[WARN][%d] (%s:%d) " M "\n", getpid(), __FILE__, __LINE__, ##__VA_ARGS__) 22 | #define info(M, ...) fprintf(stderr, "[INFO][%d] (%s:%d) " M "\n", getpid(), __FILE__, __LINE__, ##__VA_ARGS__) 23 | 24 | #define die(M, ...) fprintf(stderr, "[FATAL][%d] (%s:%d) " M "\n", getpid(), __FILE__, __LINE__, ##__VA_ARGS__); exit(1); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /myBigInt/CBigInt.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/myBigInt/CBigInt.cpp -------------------------------------------------------------------------------- /myBigInt/CBigInt.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/myBigInt/CBigInt.h -------------------------------------------------------------------------------- /myBigInt/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/myBigInt/main.cpp -------------------------------------------------------------------------------- /simpletest.h: -------------------------------------------------------------------------------- 1 | #ifndef UNITTEST_H 2 | #define UNITTEST_H 3 | #include 4 | 5 | 6 | 7 | #define TEST_OK 0 8 | #define TEST_RESULT char* 9 | #define TEST_ASSERT(message, test) do { if (!(test))return message; } while (0); 10 | #define RUN_TEST(test) do { \ 11 | char *message = test(); \ 12 | nr_tests_run++;\ 13 | if (message){printf("Test nr %d: " #test "( %s ) FAILED !!! \n",nr_tests_run,message);return message;}\ 14 | else{printf("Test nr %d: " #test " OK...\n",nr_tests_run);} \ 15 | } while (0); 16 | 17 | #define DECLARE_FIXTURE(name) char* run_tests_##name(){\ 18 | puts("\n\n Testing fixture: " #name);\ 19 | puts("______________________________\n");\ 20 | int nr_tests_run=0; 21 | 22 | #define END_FIXTURE return 0;} 23 | #define RUN_FIXTURE(name) do{ if(run_tests_##name()==0) {printf("ALL TESTS PASSED\n"); } }while(0); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /simpletest_main.c: -------------------------------------------------------------------------------- 1 | // create a test 2 | #include "simpletest.h" 3 | 4 | 5 | TEST_RESULT test1() 6 | { 7 | int x = 2; 8 | 9 | TEST_ASSERT("x equal with 2", x == 2); 10 | 11 | return TEST_OK; 12 | } 13 | 14 | //create another test 15 | TEST_RESULT test2() 16 | { 17 | int w = 2; 18 | TEST_ASSERT("w equal 3", w == 3); 19 | 20 | return TEST_OK; 21 | } 22 | 23 | 24 | //group tests in fixtures 25 | DECLARE_FIXTURE(numbers) 26 | RUN_TEST(test1) 27 | RUN_TEST(test2) 28 | END_FIXTURE 29 | 30 | 31 | DECLARE_FIXTURE(numbers2) 32 | RUN_TEST(test1) 33 | END_FIXTURE 34 | 35 | 36 | 37 | int main(int argc, char *argv[]) { 38 | 39 | //run the fixtures 40 | RUN_FIXTURE(numbers) 41 | RUN_FIXTURE(numbers2) 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /sort_坑.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/sort_坑.cpp -------------------------------------------------------------------------------- /string_buffer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 Zhiyuan Wang 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "string_buffer.h" 13 | 14 | 15 | static 16 | int expand_buffer(StringBuffer *self, size_t min) 17 | { 18 | char *new_buf = NULL; 19 | size_t new_capacity = 0; 20 | 21 | min = min + 1 - (self->capacity - self->length); 22 | if (min <= 0) return 0; 23 | 24 | new_capacity = self->capacity + (min / STEP_LENGTH + 1) * STEP_LENGTH; 25 | new_buf = realloc(self->buf, new_capacity); 26 | if (new_buf != NULL) { 27 | self->buf = new_buf; 28 | memset(self->buf + self->capacity, 0, new_capacity - self->capacity); 29 | self->capacity = new_capacity; 30 | return 0; 31 | } else { 32 | return -1; 33 | } 34 | } 35 | 36 | StringBuffer *string_buffer_new() 37 | { 38 | StringBuffer *self = NULL; 39 | 40 | self = calloc(1, sizeof(*self)); 41 | if (self != NULL) { 42 | self->buf = calloc(1, STEP_LENGTH); 43 | if (self->buf != NULL) { 44 | self->capacity = STEP_LENGTH; 45 | } else { 46 | free(self); 47 | self = NULL; 48 | } 49 | } 50 | return self; 51 | } 52 | 53 | void string_buffer_delete(StringBuffer *self) 54 | { 55 | if (self) { 56 | if (self->buf) { 57 | free(self->buf); 58 | } 59 | free(self); 60 | } 61 | } 62 | 63 | size_t string_buffer_length(StringBuffer *self) 64 | { 65 | return self ? self->length : 0; 66 | } 67 | 68 | size_t string_buffer_capacity(StringBuffer *self) 69 | { 70 | return self ? (self->capacity - 1) : 0; 71 | } 72 | 73 | char *string_buffer_get_string(StringBuffer *self) 74 | { 75 | return self ? self->buf : NULL; 76 | } 77 | 78 | void string_buffer_clear(StringBuffer *self) 79 | { 80 | if (self != NULL) { 81 | memset(self->buf, 0, self->length); 82 | self->length = 0; 83 | } 84 | } 85 | 86 | int string_buffer_append(StringBuffer *self, const char *str) 87 | { 88 | return string_buffer_append_n(self, str, strlen(str)); 89 | } 90 | 91 | int string_buffer_append_n(StringBuffer *self, const char *str, size_t n) 92 | { 93 | if (self == NULL) return -1; 94 | 95 | EXPAND_BUFFER(self, n); 96 | memcpy(self->buf + self->length, str, n); 97 | self->length += n; 98 | self->buf[self->length] = '\0'; 99 | return n; 100 | } 101 | 102 | int string_buffer_appendf(StringBuffer *self, const char *format, ...) 103 | { 104 | size_t n = 0; 105 | int ret = 0; 106 | va_list args; 107 | 108 | if (self == NULL) return -1; 109 | 110 | while (1) { 111 | n = self->capacity - self->length; 112 | va_start(args, format); 113 | ret = vsnprintf(self->buf + self->length, n, format, args); 114 | va_end(args); 115 | 116 | if (ret >= 0 && ret < n) { 117 | self->length += ret; 118 | return ret; 119 | } else if (ret < 0) { 120 | // error 121 | return ret; 122 | } else { 123 | // no enough space in buffer 124 | if (expand_buffer(self, ret - n)) { 125 | // expand failed 126 | return -1; 127 | } 128 | } 129 | } 130 | return ret; 131 | } 132 | 133 | int string_buffer_append_set(StringBuffer *self, int value, size_t num) 134 | { 135 | if (self == NULL) return -1; 136 | 137 | EXPAND_BUFFER(self, num); 138 | 139 | memset(self->buf + self->length, value, num); 140 | self->length += num; 141 | self->buf[self->length] = '\0'; 142 | return num; 143 | } 144 | -------------------------------------------------------------------------------- /string_buffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 Zhiyuan Wang 5 | */ 6 | 7 | #ifndef _STRING_BUFFER_H_ 8 | #define _STRING_BUFFER_H_ 9 | 10 | 11 | 12 | #define STEP_LENGTH 512 13 | 14 | #define EXPAND_BUFFER(self, n) \ 15 | if (expand_buffer(self, (n))) { \ 16 | return -1; \ 17 | } \ 18 | 19 | 20 | struct StringBuffer { 21 | size_t length; 22 | size_t capacity; 23 | char *buf; 24 | }; 25 | 26 | 27 | /** 28 | * A buffer of C string. 29 | */ 30 | typedef struct StringBuffer StringBuffer; 31 | 32 | /** 33 | * Create a new buffer initialized to zero, return NULL if fail. 34 | */ 35 | extern StringBuffer *string_buffer_new(); 36 | 37 | /** 38 | * Delete a StringBuffer. 39 | */ 40 | extern void string_buffer_delete(StringBuffer *self); 41 | 42 | /** 43 | * Get length of data in the buffer. 44 | */ 45 | extern size_t string_buffer_length(StringBuffer *self); 46 | 47 | /** 48 | * Get capacity of the buffer. 49 | */ 50 | extern size_t string_buffer_capacity(StringBuffer *self); 51 | 52 | /** 53 | * Get the string. 54 | */ 55 | extern char *string_buffer_get_string(StringBuffer *self); 56 | 57 | /** 58 | * Clear all data in the buffer. 59 | */ 60 | extern void string_buffer_clear(StringBuffer *self); 61 | 62 | /** 63 | * Add string to the buffer. 64 | * Return length of str on success, -1 on failure. 65 | */ 66 | extern int string_buffer_append(StringBuffer *self, const char *str); 67 | 68 | /** 69 | * Add the first n bytes of str to the buffer. 70 | * Return n on success, -1 on failure. 71 | */ 72 | extern int string_buffer_append_n(StringBuffer *self, const char *str, size_t n); 73 | 74 | /** 75 | * Add data to the buffer, the format specifier is the same with printf. 76 | * Return value is the number of characters that has been written to the buffer, 77 | * not counting the terminating null character. 78 | */ 79 | extern int string_buffer_appendf(StringBuffer *self, const char *format, ...); 80 | 81 | /** 82 | * Sets the n bytes of the tail of buffer to the specified value. 83 | * Return n on sucess, -1 on failure. 84 | */ 85 | extern int string_buffer_append_set(StringBuffer *self, int value, size_t n); 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /stringx/stringx.c: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_DEPRECATE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "stringx.h" 7 | 8 | 9 | 10 | char* string_malloc(size_t len) 11 | { 12 | char* ret=(char*)malloc(len+1); 13 | if(ret!=NULL) 14 | { 15 | ret[len]='\0'; 16 | 17 | } 18 | return ret; 19 | 20 | } 21 | 22 | char* string_clone(const char* str) 23 | { 24 | if(str!=NULL) 25 | { 26 | char* ret=string_malloc(strlen(str)); 27 | if(ret) 28 | { 29 | strcpy(ret,str); 30 | return ret; 31 | } 32 | } 33 | return NULL; 34 | } 35 | 36 | int string_equal(const char* s1,const char* s2) 37 | { 38 | if(s1==NULL || s2==NULL) return 0; 39 | return (strcmp(s1,s2)==0); 40 | } 41 | 42 | 43 | 44 | int string_isNullOrEmpty(const char* str) 45 | { 46 | if(str!=NULL && str[0]!='\0')return 0; 47 | return 1; 48 | 49 | } 50 | 51 | int string_countOccurence(const char* str,const char* token) 52 | { 53 | int x=0; 54 | if(!string_isNullOrEmpty(str) && !string_isNullOrEmpty(token)) 55 | { 56 | 57 | char* temp=(char*)str; 58 | while((temp=strstr(temp,token))!=NULL) 59 | { 60 | temp+=strlen(token); 61 | x++; 62 | } 63 | } 64 | return x; 65 | } 66 | 67 | 68 | 69 | char* string_replace(const char* str,const char* oldval,const char* newval) 70 | { 71 | if(!string_isNullOrEmpty(str) && !string_isNullOrEmpty(oldval) && !string_isNullOrEmpty(newval)) 72 | { 73 | 74 | int oc=string_countOccurence(str,oldval); 75 | 76 | if(oc>0) 77 | { 78 | size_t diff=strlen(newval)-strlen(oldval); 79 | size_t nsize=strlen(str)+oc*diff+1; 80 | 81 | char* buff=(char*) calloc(1,nsize); 82 | 83 | if(buff!=NULL) 84 | { 85 | char* temp=NULL; 86 | char* mark=(char*)str; 87 | 88 | while((temp=strstr(mark,oldval))!=NULL) 89 | { 90 | 91 | size_t off=strlen(mark)-strlen(temp); 92 | 93 | strncat(buff,mark,off); 94 | strncat(buff,newval,strlen(newval)); 95 | 96 | temp+=strlen(oldval); 97 | mark=temp; 98 | } 99 | 100 | strncat(buff,mark,strlen(mark)); 101 | 102 | return buff; 103 | } 104 | 105 | free(buff); 106 | 107 | } 108 | 109 | } 110 | return NULL; 111 | } 112 | 113 | 114 | char* string_extractBetweenTokens(const char* str,const char* tokenstart,const char* tokenend) 115 | { 116 | if(!string_isNullOrEmpty(str) && !string_isNullOrEmpty(tokenstart) && !string_isNullOrEmpty(tokenend)) 117 | { 118 | char* tok1=strstr((char*)str,tokenstart); 119 | if(tok1!=NULL) 120 | { 121 | tok1+=strlen(tokenstart); 122 | char* tok2=strstr(tok1,tokenend); 123 | 124 | if(tok2!=NULL) 125 | { 126 | size_t off=strlen(tok1)-strlen(tok2); 127 | char* buff=(char*)calloc(1,off+1); 128 | strncpy(buff,tok1,off); 129 | return buff; 130 | } 131 | 132 | } 133 | 134 | } 135 | return NULL; 136 | 137 | } 138 | 139 | 140 | 141 | char* string_replaceBetweenTokens(const char* str,const char* tokenstart,const char* tokenend,const char* val,TokensInclusion withtokens) 142 | { 143 | if(!string_isNullOrEmpty(str) && !string_isNullOrEmpty(tokenstart) && !string_isNullOrEmpty(tokenend) && !string_isNullOrEmpty(val)) 144 | { 145 | char* tok1=strstr((char*)str,tokenstart); 146 | if(tok1!=NULL) 147 | { 148 | if(withtokens==In) 149 | { 150 | tok1+=strlen(tokenstart); 151 | 152 | } 153 | 154 | size_t dift1=strlen(str)-strlen(tok1); 155 | char* tok2=strstr(tok1,tokenend); 156 | 157 | if(tok2!=NULL) 158 | { 159 | if(withtokens==Out) 160 | { 161 | tok2+=strlen(tokenend); 162 | } 163 | size_t newsize=dift1+strlen(val)+strlen(tok2); 164 | char* buff=(char*)calloc(1,newsize+1); 165 | 166 | strncat(buff,str,dift1); 167 | strcat(buff,val); 168 | strcat(buff,tok2); 169 | 170 | return buff; 171 | 172 | 173 | } 174 | 175 | } 176 | 177 | 178 | } 179 | 180 | return NULL; 181 | } 182 | 183 | 184 | unsigned int string_startsWith(const char* str,const char* token) 185 | { 186 | if(str==NULL || token==NULL)return 0; 187 | return (strncmp(str,token,strlen(token))==0); 188 | 189 | } 190 | 191 | unsigned int string_endsWith(const char* str,const char* token) 192 | { 193 | 194 | if(!string_isNullOrEmpty(str) && !string_isNullOrEmpty(token)) 195 | { 196 | int off=strlen(str)-strlen(token); 197 | if(off>=0) 198 | { 199 | char* temp=(char*)str; 200 | temp+=off; 201 | return (strncmp(temp,token,strlen(token))==0); 202 | } 203 | } 204 | return 0; 205 | 206 | } 207 | 208 | 209 | int iterate_split_result(split_result* res,char** val) 210 | { 211 | if(res && res->nr>0) 212 | { 213 | static int idx=-1; 214 | if(idx>=(res->nr-1))return 0; 215 | 216 | idx++; 217 | (*val)=res->tokens[idx]; 218 | return 1; 219 | } 220 | return 0; 221 | } 222 | void free_split_result(split_result* res) 223 | { 224 | if(res && res->nr>0) 225 | { 226 | int x; 227 | for(x=0;xnr;x++) 228 | { 229 | free(res->tokens[x]); 230 | res->tokens[x]=NULL; 231 | } 232 | } 233 | free(res->tokens); 234 | res->tokens=NULL; 235 | 236 | free(res); 237 | res=NULL; 238 | } 239 | 240 | split_result* string_split_result(const char* text,const char* delim,int maxnr) 241 | { 242 | if(!maxnr)maxnr=100; 243 | 244 | split_result* result=malloc(sizeof(split_result)); 245 | result->tokens=malloc(maxnr*sizeof(char*)); 246 | result->nr=0; 247 | 248 | char* temp=(char*)text; 249 | 250 | while(1) 251 | { 252 | char* back=temp; 253 | temp=strstr(temp,delim); 254 | if(temp) 255 | { 256 | 257 | if(maxnr<=(result->nr))break; 258 | 259 | int off=strlen(back)-strlen(temp); 260 | temp+=strlen(delim); 261 | if(off<=0) 262 | { 263 | continue; 264 | } 265 | char* word=malloc(off+1); 266 | strncpy(word,back,off); 267 | word[off]='\0'; 268 | 269 | 270 | result->tokens[result->nr]=word; 271 | result->nr++; 272 | 273 | } 274 | else 275 | { 276 | break; 277 | } 278 | 279 | } 280 | return result; 281 | 282 | } 283 | 284 | int string_split(const char* text,const char* delim,char*** tokens,int maxnr) 285 | { 286 | char* temp=(char*)text; 287 | int nrtokens=0; 288 | 289 | if(!maxnr) 290 | { 291 | maxnr=100; 292 | } 293 | 294 | (*tokens)=malloc(maxnr*sizeof(char*)); 295 | 296 | while(1) 297 | { 298 | char* back=temp; 299 | temp=strstr(temp,delim); 300 | if(temp) 301 | { 302 | 303 | 304 | if(maxnr<=(nrtokens))break; 305 | 306 | int off=strlen(back)-strlen(temp); 307 | temp+=strlen(delim); 308 | if(off<=0) 309 | { 310 | continue; 311 | } 312 | char* word=malloc(off+1); 313 | strncpy(word,back,off); 314 | word[off]='\0'; 315 | 316 | 317 | (*tokens)[nrtokens]=word; 318 | nrtokens++; 319 | 320 | } 321 | else 322 | { 323 | break; 324 | } 325 | 326 | } 327 | return nrtokens; 328 | } 329 | 330 | 331 | char* string_trimLeft(const char* str) 332 | { 333 | if(!string_isNullOrEmpty(str)) 334 | { 335 | int off=0; 336 | while(1) 337 | { 338 | 339 | if(str[off]==' ') 340 | { 341 | off++; 342 | } 343 | else 344 | { 345 | break; 346 | } 347 | } 348 | 349 | if(off>0 && off=0;x--) 375 | { 376 | 377 | if(str[x]==' ') 378 | { 379 | off++; 380 | } 381 | else 382 | { 383 | break; 384 | } 385 | 386 | } 387 | 388 | if(off>0 && off0) 452 | { 453 | 454 | strncat(buf,old,diff); 455 | 456 | } 457 | 458 | old=temp+1; 459 | temp=strpbrk(old,keys); 460 | if(temp==NULL) 461 | { 462 | strncat(buf,old,strlen(old)); 463 | break; 464 | } 465 | } 466 | return buf; 467 | } 468 | 469 | return NULL; 470 | 471 | } 472 | 473 | 474 | 475 | 476 | char* string_join(const char* str1,const char* str2) 477 | { 478 | if(str1==NULL && str2==NULL) 479 | { 480 | return NULL; 481 | } 482 | 483 | size_t sz1=0; 484 | size_t sz2=0; 485 | 486 | 487 | 488 | if(str1!=NULL)sz1=strlen(str1); 489 | if(str2!=NULL)sz2=strlen(str2); 490 | 491 | char* ret=(char*)calloc(sz1+sz2+1,sizeof(char)); 492 | if(ret!=NULL) 493 | { 494 | if(str1!=NULL) 495 | { 496 | ret=strcat(ret,str1); 497 | } 498 | if(str2!=NULL) 499 | { 500 | ret=strcat(ret,str2); 501 | } 502 | 503 | return ret; 504 | } 505 | 506 | return NULL; 507 | 508 | 509 | } 510 | 511 | 512 | 513 | int string_resize(char** str,size_t newsz) 514 | { 515 | if(newsz<=0)return 0; 516 | 517 | size_t strsz=strlen(*str); 518 | if(strsz==newsz)return 1; 519 | else 520 | { 521 | char* temp=(char*)realloc(*str,newsz+1); 522 | if(temp) 523 | { 524 | *str=temp; 525 | if(newsz': 646 | sprintf(buf,"%s",">"); 647 | break; 648 | default: 649 | sprintf(buf,"%c",str[x]); 650 | } 651 | strcat(ret,buf); 652 | x++; 653 | } 654 | free(buf); 655 | return ret; 656 | 657 | } 658 | return NULL; 659 | 660 | 661 | 662 | } 663 | 664 | char* string_urlEncode(const char* str) 665 | { 666 | 667 | if(str!=NULL) 668 | { 669 | int x=0; 670 | size_t len=strlen(str); 671 | char* ret=(char*)calloc(3*len+1,sizeof(char)); 672 | if(ret==NULL)return NULL; 673 | 674 | char* buf=(char*)calloc(10,sizeof(char)); 675 | if(buf==NULL) 676 | { 677 | free(ret); 678 | return NULL; 679 | } 680 | 681 | while(x 8 | #include 9 | #include 10 | #include 11 | 12 | #include "string_buffer.h" 13 | 14 | static 15 | void test_new_delete() 16 | { 17 | StringBuffer *sb = string_buffer_new(); 18 | string_buffer_delete(sb); 19 | string_buffer_delete(NULL); 20 | } 21 | 22 | static 23 | void test_append() 24 | { 25 | int ret; 26 | StringBuffer *sb; 27 | sb = string_buffer_new(); 28 | ret = string_buffer_append(sb, "123456"); 29 | assert(ret == 6); 30 | ret = string_buffer_append(sb, "123456"); 31 | assert(string_buffer_length(sb) == 12); 32 | assert(strcmp(string_buffer_get_string(sb), "123456123456") == 0); 33 | string_buffer_delete(sb); 34 | } 35 | 36 | static 37 | void test_append_n() 38 | { 39 | int ret; 40 | StringBuffer *sb; 41 | sb = string_buffer_new(); 42 | ret = string_buffer_append_n(sb, "123456", 4); 43 | assert(ret == 4); 44 | string_buffer_append_n(sb, "56999", 2); 45 | assert(string_buffer_length(sb) == 6); 46 | assert(strcmp(string_buffer_get_string(sb), "123456") == 0); 47 | string_buffer_delete(sb); 48 | } 49 | 50 | static 51 | void test_appendf() 52 | { 53 | int ret; 54 | StringBuffer *sb; 55 | sb = string_buffer_new(); 56 | ret = string_buffer_appendf(sb, "%05d", 1); 57 | assert(ret == 5); 58 | assert(strcmp(string_buffer_get_string(sb), "00001") == 0); 59 | string_buffer_appendf(sb, "%s", "hello"); 60 | assert(string_buffer_length(sb) == 10); 61 | assert(strcmp(string_buffer_get_string(sb), "00001hello") == 0); 62 | string_buffer_delete(sb); 63 | } 64 | 65 | static 66 | void test_append_set() 67 | { 68 | int ret; 69 | StringBuffer *sb; 70 | sb = string_buffer_new(); 71 | ret = string_buffer_append_set(sb, ' ', 5); 72 | assert(ret == 5); 73 | assert(string_buffer_length(sb) == 5); 74 | string_buffer_append_set(sb, 'a', 5); 75 | assert(string_buffer_length(sb) == 10); 76 | assert(strcmp(string_buffer_get_string(sb), " aaaaa") == 0); 77 | string_buffer_delete(sb); 78 | } 79 | 80 | static 81 | void test_clear() 82 | { 83 | StringBuffer *sb; 84 | sb = string_buffer_new(); 85 | string_buffer_append(sb, "123456"); 86 | string_buffer_clear(sb); 87 | assert(string_buffer_length(sb) == 0); 88 | assert(strcmp(string_buffer_get_string(sb), "") == 0); 89 | string_buffer_delete(sb); 90 | } 91 | 92 | static 93 | void test_buffer() 94 | { 95 | int ret = 0; 96 | char data[10240 + 1]; 97 | StringBuffer *sb = NULL; 98 | 99 | sb = string_buffer_new(); 100 | 101 | for (int i = 0; i < sizeof(data); ++i) { 102 | memset(data, '1', i); 103 | data[i] = '\0'; 104 | ret = string_buffer_append(sb, data); 105 | assert(string_buffer_length(sb) == i); 106 | assert(strcmp(string_buffer_get_string(sb), data) == 0); 107 | assert(string_buffer_capacity(sb) == (i / 512 + 1) * 512 - 1); 108 | 109 | string_buffer_clear(sb); 110 | } 111 | string_buffer_delete(sb); 112 | } 113 | 114 | int main(int argc, char const *argv[]) 115 | { 116 | test_new_delete(); 117 | test_append(); 118 | test_append_n(); 119 | test_appendf(); 120 | test_append_set(); 121 | test_clear(); 122 | test_buffer(); 123 | printf("test ok\n"); 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /位运算.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/位运算.cpp -------------------------------------------------------------------------------- /动态字符串链接.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/动态字符串链接.cpp -------------------------------------------------------------------------------- /字符串替换.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/字符串替换.c -------------------------------------------------------------------------------- /工具包/copyfile.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/工具包/copyfile.zip -------------------------------------------------------------------------------- /开房数据查询.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yunshouhu/cpp_tool/6494e7d8149112ae01a474dad2ef9108f6654d9a/开房数据查询.cpp -------------------------------------------------------------------------------- /进制转换.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | string transform(int x, int y, string s) 6 | { 7 | string res = ""; 8 | int sum = 0; 9 | for (unsigned int i = 0; i < s.length(); ++i) 10 | { 11 | if (s[i] == '-') continue; 12 | if (s[i] >= '0' && s[i] <= '9') 13 | { 14 | sum = sum*x + s[i] - '0'; 15 | } 16 | else { 17 | sum = sum*x + s[i] - 'A' + 10; 18 | 19 | } 20 | 21 | } 22 | while (sum) 23 | { 24 | char temp = sum %y; 25 | sum /= y; 26 | if (temp <= 9) 27 | { 28 | temp += '0'; 29 | } 30 | else { 31 | temp = temp - 10 + 'A'; 32 | } 33 | res = temp + res; 34 | } 35 | if (res.length() == 0) res = "0"; 36 | if (s[0] == '-') 37 | res = '-' + res; 38 | return res; 39 | } 40 | int main(int argc, char* argv) 41 | { 42 | 43 | cout << transform(10,2,"1024") << endl; 44 | cout << transform(10, 16, "1024") << endl; 45 | cout << transform(10, 8, "1024") << endl; 46 | cout << transform(8, 10, "1024") << endl; 47 | cout << transform(8, 16, "1024") << endl; 48 | cout << transform(16, 10, "1024") << endl; 49 | cout << transform(2, 10, "10000010") << endl; 50 | cout << transform(2, 16, "10000010") << endl; 51 | 52 | int aa,bb,cc,dd; 53 | 54 | aa = bb = cc = dd = 1; 55 | aa = bb = cc = dd = 1; 56 | aa = bb = cc = dd = 1; 57 | 58 | (aa + 1 == 2) ? bb = aa + 2 : aa + 3; 59 | cout << aa << bb << endl; 60 | 61 | 62 | char A[]= "He has tez !"; 63 | cout << strlen(A) << endl; 64 | return 0; 65 | } 66 | --------------------------------------------------------------------------------