#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "uthash.h"
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
fmin(a, b) --- c语言库函数,返回两个浮点参数中的较小者
fmax(a, b) --- c语言库函数,返回两个浮点参数中的较大者
----------------------------------------------------------------------
strlen();字符串长度,不包含结束符
strcmp(str1, str2); str1与str2相同返回0
strncmp(str1, str2, n) 用来比较str1和str2字符串的前n个字符。如果两个字符串相等的话,strncmp将返回0。如果str1是str2的一个子串的话,str1小于str2。
strstr(str1, str2);该库函数包含在<string.h>头文件中意义为判断str2是否为str1的子串,若是则返回str2在str1中首次出现的指针位置,若不是返回NULL;
strchr(str, ch);功能就是找出在字符串str中第一次出现字符ch的位置,找到就返回该字符位置的指针,找不到就返回NULL
strset(str, ch);str字符串的所有字符替换为ch
strnset(str, ch, n); str字符串的前n个字符替换为ch
strcat(str1, str2); str2添加到str1的结尾
strncat(str1, str2,n); str2添加到str1的结尾,复制n个字符
strcpy(str1, str2); 把str2复制到str1
strncpy(str1, str2 + m, n); 从str2中第str[m]开始的n个字符复制到str1
strtok(str, delim);字符串str根据delim分割为多个子字符串
---------------------
char *token[col];
int i = 0;
/* 获取第一个子字符串 */
token[0] = strtok(str, ",");
/* 继续获取其他的子字符串 */
while( token[i] != NULL ) {
token[++i] = strtok(NULL, ",");
}
----------------------------------------------------------------------
sprintf就是printf打印到str字符串中,返回值表示本次函数调用最终打印到字符缓冲区中的字符数目。
//将整数hh,mm,ss按指定格式组合后写入到字符串str中
sprintf(str,"%d:%d:%d",hh,mm,ss);
1、将数字转换为字符串形式:
char numstr[10] = {0};
sprintf(numstr, "%d", num);
2、字符串转换成整数形式:
int numtemp = atoi(numstr);
----------------------------------------------------------------------
sscanf()返回值,成功则返回参数数目
//取指定长度(4个)的字符串到str
(1)sscanf("zhoue3456 ", "%4s", str);
//取到指定字符为止的字符串,取遇到空格为止字符串
(2)sscanf("zhou456 hedf", "%[^ ]", str);
//取仅包含指定字符集的字符串(只取数字和小写字符)
(3)sscanf("654321abcdedfABCDEF", "%[1-9a-z]", str);
//取需要的字符串
(4)sscanf("2015.04.05", "%d.%d.%d", &a,&b,&c);
//取出&与$之间的字符串
(5)sscanf("abcd&hello$why", "%*[^&]&%[^$]", str );
//“what, time”仅保留time
(6)sscanf(“what, time”, "%*s%s", str );
注:
(*) 表示跳过此数据不读入
%[set]匹配输入字符串中所有在set字符集中的字符,遇见非set字符集的字符时即停止
%[^set]表示非
“.”为通配符,表示任何一个字符,例如:“a.c”可以匹配“anc”、“abc”、“acc”;
“|”或运算符,例如:a[n|bc|cb]c可以匹配“abcc”,“anc”,“acbc”;
----------------------------------------------------------------------
strcat_s(str1, sizeof(str1), str2); str2添加到str1的结尾
strncpy_s(str1, sizeof(str1), str2 + m, n); 从str2中第str[m]开始的n个字符复制到str1
memcpy_s(str1, sizeof(str1), str2, sizeof(str2)); str2复制到str1
strcpy_s(str1, sizeof(str1), str2, sizeof(str2)); 把str2复制到str1
sprintf_s(buffer, 200, " String: %s\n", s );
memset_s(void *dest, size_t destMax, int c, size_t count);
----------------------------------------------------------------------
*************************滑动窗口*************************
滑动窗口法,可以用来解决一些查找满足一定条件的连续区间的性质(长度等)的问题。往往类似于“请找到满足xx的最x的区间(子串、子数组)的xx”,
一般新建两个指针,初始化指向初始位置left = right = 0,索引闭区间[left, right]就是一个窗口,我们首先增加right指针扩大窗口,直到窗口中的字符串符合要求,之后,转而增加left指针缩小窗口,直到窗口中的字符串不符合要求,每次增加left都要更新一轮结果,然后重复此动作,直到right到达尽头。
滑动窗口就是双指针算法,只不过两个指针都先指向初始位置,还有的双指针是一个指向首地址,一个指向尾地址。
例:209. 长度最小的子数组(中等)
// 0、"子数组"问题使用滑动窗口。
// 1、满足什么条件,更新数据?------窗口内数据和大于target 。
// 2、更新什么数据?------最小子数组的长度,满足条件窗口的最小长度。
int minSubArrayLen(int s, int *nums, int numsSize) {
if (numsSize == 0) {
return 0;
}
int minlen = INT_MAX;
int left = 0, right = 0;
int sum = 0;
/* 1、右指针到数组或字符串最大长度截止*/
while (right < numsSize) {
sum += nums[right];
while (sum >= s) { /* 满足条件 */
minlen = fmin(minlen, right - left + 1); /*更新数据 */
sum -= nums[left];
left++; /* 窗口收缩,左移窗口 */
}
right++; /* 右移窗口 */
}
return minlen == INT_MAX ? 0 : minlen;
}
*************************双指针*************************
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
你不需要考虑数组中超出新长度后面的元素。
int removeElement(int* nums, int numsSize, int val){
int slow = 0;
for(int fast = 0; fast < numsSize; fast++) {
//若快指针位置的元素不等于要删除的元素
if(nums[fast] != val) {
//将其挪到慢指针指向的位置,慢指针+1
nums[slow++] = nums[fast];
}
}
//最后慢指针的大小就是新的数组的大小
return slow;
}
*************************排序函数 stdlib.h*************************
/* 大小 */
int comp(const void *a, const void *b){
return *(int*)b - *(int*)a;
}
int cmp(const void *a, const void *b)
{
return *((int*)a) > *((int*)b) ? 1 : *((int*)a) < *((int*)b) ? -1 : 0;
}
/* 字典序排序,如果第一个相同就排第二个 [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] */
int cmp(const void *str1, const void *str2)
{
const char **tmp1 = *(char**)str1;
const char **tmp2 = *(char**)str2;
int ret = strcmp(tmp1[0], tmp2[0]);
if (ret == 0) {
return strcmp(tmp1[1], tmp2[1]);
}
return ret;
}
/* 按照第一列的数排序 */
int cmp(const void *a, const void *b)
{
return *((int **)a)[0] - *((int **)b)[0];
}
/* 字符串长度长到短排序 */
int comp(const void *a, const void *b)
{
return strlen(*(const char **)b) - strlen(* (const char **)a);
}
typedef struct {
char keyword[10];
int year;
} FilterSystem;
int cmp( void *a, void *b){
return strcmp((*(FilterSystem **)a)->keyword, (*(FilterSystem **)b)->keyword);
}
int main()
{
FilterSystem **hhh = malloc(2 * sizeof(FilterSystem *));
for (int i = 0; i < 2; i++) {
hhh[i] = malloc(sizeof(FilterSystem));
}
memset(hhh[0], 0, sizeof(FilterSystem));
memset(hhh[1], 0, sizeof(FilterSystem));
strcpy(hhh[0]->keyword, "ccccc");
hhh[0]->year = 9;
strcpy(hhh[1]->keyword, "bbbb");
hhh[1]->year = 8;
qsort(hhh, 2, sizeof(FilterSystem*), cmp);
return 0;
}
typedef struct {
char keyword[100]; // 预留1000个关键词,每个关键词20字符
} FilterSystem;
int cmp (const void *a, const void *b) {
FilterSystem *aa = (FilterSystem *)a;
FilterSystem *bb = (FilterSystem *)b;
return strlen(bb->keyword) - strlen(aa->keyword);
}
int main()
{
FilterSystem hh[10] = {0};
strcpy(hh[0].keyword, "aaa");
strcpy(hh[1].keyword, "bbbbbb");
qsort(hh, 2, sizeof(FilterSystem), cmp);
printf("%s", hh[0].keyword);
return 0;
}
qsort(a, 10, sizeof(int), comp);
*************************二分法*************************
int Bin_Search(int *nums, int numsSize, int target)
{
int counter = 0;
int befor = 0;
int after = numsSize - 1;
int mid;
// [left, right) 开区间,while (befor < after)
while (befor <= after) {// [left, right]闭区间
counter++;
mid = befor + (after - befor) / 2; // 确定中间元素
if(nums[mid] > target){ // 如果求最小值,等号放到此分支增加判断 反比例改为<
after = mid - 1; // mid已经交换过了,last往前移一位;闭区间 after = mid - 1,target 在左区间,所以[left, middle - 1]; 开区间 after = mid, target 在左区间,在[left, middle)中
} else if (nums[mid] < target) { // 如果求最大值,等号放到此分支增加判断 反比例改为>
befor = mid + 1; // mid已经交换过了,first往后移一位;target 在右区间,在[middle + 1, right)中
} else { // 结果是否为一个固定的目标值,如果不是,则不需要此分支
printf("查找次数:%d\n",counter);
return mid; // 返回位置
}
}
printf("查找次数:%d\n",counter);
return befor; //右边的值(大),与名称相反 一般返回此值
return after; //左边的值(小),与名称相反
}
*************************DFS*************************
void dfs(int step, …)
{
if (到达终点状态,满足最终解的条件,返回) {
根据题意添加
return;
}
if (判断边界条件或不合法的情况) {
相应操作,一般就直接返回错误码就行了
return;
}
for (遍历每一种可能) {
if (遍历的合法状态) {
visited[step]; // 标记已经访问过的节点
修改操作; // 根据题意来添加
dfs(); // 继续下一步
(还原标记); // 是否还原标记根据题意,如果加上(还原标记)就是回溯法
}
}
}
*************************BFS*************************
void BFS()
{
1) 初始化队列Q;
/* int queue[1000][2] = {0}; */
2) 定义2个状态,分别表示入队front和出队rear
/* int front = 0;
int rear = 0; */
3) 起点S入队,起点入队之后,入队front标记加1;
/* queue[front][0] = start;
queue[front++][1] = 0; */
4) 标记S已经访问;
/* vis[start]=1; */
while (front != rear) {
5) 已经入队的元素【出队】,入队(front)、出队(rear);
/* int a = queue[rear][0];
int b = queue[rear++][1]; */
6) if (目标状态) { //可以退出即可
返回结果;
return;
}
/* if (a == end) {
printf("%d \n", b);
return;
} */
7) for(队首元素下一层级的元素全部入队) {
if(相邻的元素合法 && 未访问) {
【入队】;
标记访问;
}
}
/* if(a + 1 <= MAXN && !vis[a+1]){
queue[front][0] = a + 1;
queue[front++][1] = b + 1;
vis[a+1] = 1;
} */
}
}
*************************并查集*************************
/* 初始化 */
int fa[MAXN];
int cnt[MAXN];
void init(int n)
{
for (int i = 0; i < n; i++) {
fa[i] = i;
cnt[i] = 1;
}
}
/* 查询 */
int find(int x)
{
return x == fa[x] ? x : (fa[x] = find(fa[x]));
}
/* x合并到y,往小的合并 */
void merge(int x, int y) {
if(find(x) < find(y)) {
cnt[find(x)] += cnt[find(y)];
fa[find(y)] = find(x);
} else if (find(x) > find(y)){
cnt[find(y)] += cnt[find(x)];
fa[find(x)] = find(y);
}
}
/* 计数 */
int count = 0; // 多少个集合
int max = 0; //每个集合有多少个元素
for (int i = 0; i < MSize; i++) {
if (fa[i] == i) {
count++;
max = max > cnt[k] ? max : cnt[k];
}
}
*************************二叉树*************************
/* 二叉树数据结构定义 */
typedef struct TreeNode {
char val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
/* 二叉树的建立--按照先序方式建立--插入 */
void CreateBiTree(struct TreeNode* *T)
{
char val;
scanf("%c",&val);
if(val == '#') {
*T = NULL; //null表示为空枝
} else {
*T = (struct TreeNode*)malloc(sizeof(TreeNode));
(*T)->val = val;
CreateBiTree(&(*T)->left);
CreateBiTree(&(*T)->right);
}
}
/* 先序遍历 根左右 */
void PreOrderTravel(struct TreeNode* T)
{
if(T == NULL) {
return;
}
printf("%c ",T->val);
PreOrderTravel(T->left);
PreOrderTravel(T->right);
}
/* 中序遍历 左根右 */
void InOrderTravel(struct TreeNode* T)
{
if(T == NULL) {
return;
}
InOrderTravel(T->left);
printf("%c ",T->val);
InOrderTravel(T->right);
}
/* 后序遍历 左右根 */
void TailOrderTravel(struct TreeNode* T)
{
if(T == NULL) {
return;
}
TailOrderTravel(T->left);
TailOrderTravel(T->right);
printf("%c ",T->val);
}
/* 计算结点个数 */
int countleaf(struct TreeNode* T)
{
if (T == NULL) {
return 0;
} else {
return countleaf(T->left) + countleaf(T->right) + 1;
}
}
*************************位运算*************************
^ 异或 a = 1001, b = 1100, a^b = 0101
|或 两边都计算,再判断结果 a | b = 1101
|| 或 先计算左边的,然后判断。是fault再运算右边的
~反 ~1 = 0 ~0 = 1
x的指定的y位置1 x| = (1<<y)
x的指定的y位置0 x& = ~(1<<y)
x的指定的y位取反 x^ = (1<<y)
获取x的y位的值 (x >> y &1)
*************************指针申请*************************
1) int *visited = (int *)malloc(accountsSize * sizeof(int));
memset(visited,0,accountsSize * sizeof(int));
2) int **rslt = (int**)malloc(intervalsSize*sizeof(int*));
for(i=0;i<intervalsSize;i++) {
rslt[i] =(int*)malloc(2*sizeof(int));
}
3) char ***res_accounts = malloc(sizeof(char **) * 1000);
for(int i = 0; i < 1000; i++) {
res_accounts[i] = malloc(sizeof(char *) * 10);
for(int j = 0; j < 10; j++) {
res_accounts[i][j] = malloc(sizeof(char) * 30);
}
}
*************************哈希表 uthash.h*************************
/* 往哈希表中添加一个对象 */
struct hash_entry {
int ikey;
char name[10];
UT_hash_handle hh;
};
struct hash_entry *g_users = NULL;
void add_user(int ikey, char *value)
{
struct hash_entry *s;
HASH_FIND_INT(g_users, &ikey, s);
if(s == NULL) {
s = (struct hash_entry*)malloc(sizeof(struct hash_entry));
s->ikey = ikey;
HASH_ADD_INT(g_users, ikey, s);
}
strcpy(s->value, value);
}
/* 在哈希表中查找一个对象 */
struct hash_entry *find_user(int ikey)
{
struct hash_entry *s;
HASH_FIND_INT(g_users, &ikey, s );
return s;
}
/* 从哈希表中删除一个对象 */
void delete_user(int ikey)
{
struct hash_entry *s = NULL;
HASH_FIND_INT(g_users, &ikey, s);
if (s != NULL) {
HASH_DEL(g_users, s);
free(s);
}
}
/* 计数 */
int num_users = HASH_COUNT(g_users);
/* 排序 comp与qsort的排序相同 */
void sort()
{
HASH_SORT(g_users, comp);
}
-------------------------------------------------------------------
int name_sort(struct hash_entry *a, struct hash_entry *b)
{
return strcmp(a->name,b->name);
}
int id_sort(struct hash_entry *a, struct hash_entry *b)
{
return (a->id - b->id);
}
void sort_by_name()
{
HASH_SORT(g_users, name_sort);
}
void sort_by_id()
{
HASH_SORT(g_users, id_sort);
}
-------------------------------------------------------------------
/* 清空 */
void delete_all() {
struct hash_entry *current_user, *tmp;
HASH_ITER(hh, g_users, current_user, tmp) {
HASH_DEL(g_users,current_user);
free(current_user);
}
}
*************************10进制转x进制(num)*************************
while (n != 0) {
num[i] = n % x;
i++;
n = n / x;
}
*************************x进制转10进制*************************
for(int i = 0; i < len; i++) {
ans = ans * x +num[i];
}
*************************不知道输入组数*************************
while(scanf("%d", &a) != EOF)) { ... }
*************************随机数*************************
int num;
srand((unsigned)time(null));
num = rand();
*************************队列*************************
// 队列
int main()
{
// 创建队列
int queue[1000];
int start = 0;
int end = -1;
// 入队
queue[++end] = 1;
// 出队
int num = queue[start++];
// 队列长度
int queueSize = end - start + 1;
// 判断队列是否为空
int isEmpty = (start > end);
}
*************************栈*************************
数组:
int main()
{
// 创建栈
int stack[1000];
int top = -1;
// 入栈
stack[++top] = 1;
// 出栈
int num = stack[top--];
// 栈中元素个数
int stackSize = top + 1;
// 栈是否为空
int isEmpty = (top < 0);
}
1. typedef int datatype;
2.
3. //Sequence Stack 实现顺序栈,使用数组来实现
4. struct stack
5. {
6. datatype data[maxsize];
7. int top;
8. };
9.
10. typedef struct stack Stack;
11. //创建栈
12.
13. Stack s;
14. //初始化栈
15. void init()
16. {
17. s.top=-1;
18. }
19.
20. //判断栈是否为空
21. bool Empty()
22. {
23. if(s.top==-1)
24. {
25. return true;
26. }
27. else
28. {
29. return false;
30. }
31. }
32.
33. //判断栈是否已满了
34. bool full()
35. {
36. if(s.top==maxsize-1)
37. {
38. return true;
39. }
40. else
41. {
42. return false;
43. }
44. }
45.
46. //入栈
47. void Push(datatype element)
48. {
49. if(!full())
50. {
51. s.top++;
52. s.data[s.top]=element;
53. }
54. else
55. {
56. printf("栈满\n");
57. }
58. }
59.
60. //出栈
61. void Pop()
62. {
63. if(!Empty())
64. {
65. s.top--;
66. }
67. else
68. {
69. printf("栈空\n");
70. }
71. }
72.
73. //取栈顶元素
74. datatype Top()
75. {
76. if(!Empty())
77. {
78. return s.data[s.top];
79. }
80. else
81. {
82. printf("栈空\n");
83. }
84. }
85.
86. //销毁栈
87. void Destroy()
88. {
89. s.top=-1;
90. }
本文总结了C语言在LeetCode中常用的函数,包括字符串操作如strlen、strcmp、strcat等,数学库函数如fmin、fmax,以及内存管理、字符串处理、数组操作、指针应用、位运算等多个方面的函数。此外,还介绍了滑动窗口和双指针等算法技巧。
2万+

被折叠的 条评论
为什么被折叠?



