*************************** 贪心算法(局部最优解) Python中列表和集合的表示set()函数的使用 费曼算法 最长公共子串 最长公共子序列 K最近邻算法 使用vector容器把一个文件的整数排序后输出到另一个文件 牛客网共三题算法 两题简单一题中等难度,第一二题可能会是循环、数组、字符串、栈这些, 第三题会难一点,二分查找、动态规划、DFS、BFS这些。每题都有test case 算每题分数总和为总分 可看一下leetcode网的典型练习题目,编号如下: 字符串:3,49,30 线性表:86,16,27,732 队列:641,406,899 栈:946,116,117,895 哈希表:61,729,25,554 dfs:105,112,98,494,547,1254 bfs:1091,1129,102,101,752 这是牛客网题库 可以练习一下输入输出 www.newcoder.com/ta/huawei 深圳观澜丹坑村南58栋店 while True: try: a,res=int(input()),set() for i in range(a):res.add(int(input())) for i in sorted(res):print(i) except: break 第3题: 自己完成代码: while True: try: num = int(input()) arry = [] for i in range(num): arry.append(int(input())) arry = list(set(arry)) arry.sort() for j in arry: print(j) except: break split()函数实际上,split()函数默认可以按空格分割,并且把结果中的空字符串删除掉,留下有用信息 第30题: numto = {} numto["1"] = ["8"] numto["2"] = ["4"] numto["3"] = ["C"] numto["4"] = ["2"] numto["5"] = ["A"] numto["6"] = ["6"] numto["7"] = ["E"] numto["8"] = ["1"] numto["9"] = ["9"] numto["A"] = ["5"] numto["B"] = ["D"] numto["C"] = ["3"] numto["D"] = ["B"] numto["E"] = ["7"] numto["F"] = ["F"] numto["a"] = ["5"] numto["b"] = ["D"] numto["c"] = ["3"] numto["d"] = ["B"] numto["e"] = ["7"] numto["f"] = ["F"] while True: try: a =input() b = a.split(" ") c = b[0]+b[1] num = len(c) c1 = [] c2 = [] for i in range(num): if i % 2 == 0: c1.append(c[i]) else: c2.append(c[i]) c1.sort() c2.sort() new_a = [] count = 0 count1 = 0 for j in range(num): if j % 2 == 0: new_a.append(c1[count]) else: new_a.append(c2[count]) count = count + 1 new_b = [] for k in range(num): try: new_b += numto[new_a[k]] except: new_b += new_a[k] bbb = '' bbb = bbb.join(new_b) print(bbb) except: break 第49题: 单链表 反转链表思路: 需要考虑head节点是否需要存储数据 1、head不进行数据的存储 2、head节点进行数据的存储 通过,pre,cur,next节点来进行依次的翻转 编程实现一个点链表中某个位置的节点 node *search_node(node *head,int pos) { if(!head) { return NULL; } if(pos < 0) { return NULL; } node *temp = NULL; temp = head; while(--pos) { if((p = p->next) == NULL) { return NULL; } } return p; } 编程实现一个单链表节点的插入 node *insert_node(node *head,int pos,int data) { node *item = NULL; item = (node*)malloc(sizeof(node)); item->data = data; node *pre = NULL; node *next = NULL; node *cur = NULL; if(pos < 0) { return NULL; } if(!head) { return NULL; } cur = head; while(pos--) { cur = cur->next; if(cur == NULL) { return NULL; } } item->next = cur->next; cur->next = item; return head; } 单链表节点的删除 node *delete_node(node *head,int pos) { node *item = NULL; node *p = head->next; if(p == NULL) { return NULL; } if(pos < 0) { return NULL; } while(pos--) { item = p; p = p->next; if(p == NULL) { return NULL; } } item->next = p->next; free(p); p = NULL; } typedef struct node { int data; node *next; }node; node *InserSort(void) { int data; struct node *head = NULL,*new, } 单链表的合并 node *insert_node(node *head,node *item) { } 创建一个双向链表 typedef struct DbNode { int data; DbNode *left; DbNode *right; }DbNode; //根据数据创建节点 DbNode *CreateNode(int data) { DbNode *pnode = (DbNode *)malloc(sizeof(DbNode)); pnode->data = data; pnode->left = pnode->right = pnode; return pnode; } //创建链表 DbNode *CreateList(int head) { DbNode *pnode = (DbNode *)malloc(sizeof(DbNode)); pnode->data = head; pnode->left = pnode->right = pnode; return pnode; } //插入新的节点,总是在表尾节点 DbNode *AppendNode(DbNode *head, int data) { DbNode *ndoe = CreateNode(int data); if(node == NULL) { return NULL; } DbNode *cur = head; while(cur->right != NULL) { cur = cur->right; } cur->right = node; node->left = cur; ndoe->right = NULL; return head; } 双向节点的插入 void InsertNode(DbNode *node,int data) { DbNode *newnode = CreateNode(data); if(newnode == NULL) { return NULL; } if(node->right == NULL) { node->right = newnode; newnode->left = node; newnode->right = NULL; }else{ newnode->right = node->right; newnode->right->left = newnode; newnode->right = node; node->left = newnode; } } 实现一个双向链表的删除 DbNode *DeletNode(DbNode *head,int data) { DbNode *temp = head; DbNode *p = NULL; if(data < 0) { return NULL; } if(head == NULL) { return NULL; } while(temp != NULL) { temp = temp->right; if(temp->data = data) { //删除temp p = temp; p->left->right = p->right; p->right->left = p->left; temp = p->left; free(p); } } if(temp == NULL) { return NULL; } return head; } 用C++实现一个二叉排序树 typedef struct node{ int data; struct node *left; struct node *right; }Node; typedef struct tree{ Node *root; }Tree; void insert(Tree *tree,int value) { Node *node = (Node*)malloc(sizeof(Node)); node->data = value; node->right = NULL; node->left = NULL; if(tree->root == NULL) { tree->root = node; }else{ Node *temp = tree->root; while(temp != NULL) { if(value < temp->data) { if(temp->left == NULL) { temp->left = node; return; }else{ temp = temp->left } }else{ if(value >= temp->data) { if(temp->right == NULL) { temp->right = node; return ; }else{ temp = temp->right; } } } } } } //中序遍历 void traverse(Node *node) { if(node != NULL) { traverse(node->left); print("the data is %d\n",node->data); traverse(node->right); } } 排序: 1、插入排序 2、希尔排序 3、冒泡排序 4、快排 5、选择排序 6、堆排序 7、并归排序 8、基数排序 1、翻转字符串: char *solve(char *str) { int len = strlen(str); char *p = str; char *q = p + len -1; while(p < q) { char temp = *p; *p = *q; p++; q--; } return str; } 使用栈完成: #include <stdbool.h> #include <errno.h> #define OK 1 #define ERROR -1 #define MEM_OVERFLOW -2 #define DEFAULT_CAPACITY 8 #define InitStack(S) __InitStack(S, DEFAULT_CAPACITY); typedef int Status; // ----------- 顺序栈的数据存储结构的表示与实现 ------------ typedef char SElemType; typedef struct { SElemType* base; // 顺序栈存储空间基地址 SElemType* top; // 栈顶指针 int capacity; } SqStack; Status __InitStack(SqStack* S, int initialCapacity) { if (initialCapacity < 1) { printf("InitStack ERROR: The initialCapacity %d Must be > 0!", initialCapacity); return ERROR; } if (!(S->base = (SElemType*) malloc(initialCapacity * sizeof(SElemType)))) { printf("InitStack OVERFLOW: %s\n", strerror(errno)); exit(MEM_OVERFLOW); } S->top = S->base; S->capacity = initialCapacity; return OK; } bool StackEmpty(SqStack* S) { return S->top == S->base; } bool StackFull(SqStack* S) { return (S->top - S->base) == S->capacity; } size_t StackLength(SqStack* S) { return S->top - S->base; } void __largeCapacity(SqStack* S) { // 优先执行策略1: 在原先空间的尾部追加空间。(不需要移动元素) if ((S->base = (SElemType*) realloc(S->base, S->capacity << 1))) { // resize S->top = S->base + S->capacity; // important! S->capacity <<= 1; return; } puts("strategy 2"); // 策略1在原先空间后找不到一整段连续空间时,执行策略2。 SElemType* new_base = (SElemType*) malloc((S->capacity << 1) * sizeof(SElemType)); if (!new_base) { printf("__largeCapacity OVERFLOW: %s\n", strerror(errno)); exit(MEM_OVERFLOW); } memcpy(new_base, S->base, S->capacity * sizeof(SElemType)); free(S->base); S->base = new_base; S->top = new_base + S->capacity; // 栈顶指针指向新空间的栈顶位置 S->capacity <<= 1; } Status Push(SqStack* S, SElemType e) { if (StackFull(S)) __largeCapacity(S); *S->top++ = e; return OK; } Status Pop(SqStack* S, SElemType* e) { if (StackEmpty(S)) { puts("Pop ERROR: The stack is empty!"); return ERROR; } *e = *--S->top; return OK; } Status DestroyStack(SqStack* S) { free(S->base); S->base = S->top = NULL; return OK; } // ----------- 顺序栈的数据存储结构的表示与实现 ------------ /** * 反转字符串 * @param str string字符串 * @return string字符串 */ char* solve(char* str) { SqStack S; InitStack(&S); char* p = str; while (*p) Push(&S, *p++); p = str; while (!StackEmpty(&S)) Pop(&S, p++); *p = '\0'; return str; } 自己写的: char* solve(char* str ) { // write code here if(!str) { return NULL; } printf("the str is %s\n",str); char *temp = NULL; char *buff = NULL; buff = (char *)malloc(strlen(str)); int num = strlen(str); temp = str; int a = num; while(a--)//数量计算可优化 { temp++; // printf("the is is %c\n",*temp); } temp--; printf("the buff is %s\n",str); str = buff; for(int i = 0;i < num; i++)//赋值可优化 { *buff = *temp; printf("the num is %c\n",*buff); buff++; temp--; } //str = buff; printf("the str 2 is %s\n",str); return str; } 斐波那契数列: int Fibonacci(int n ) { // write code here if( n == 1 || n == 2) { return 1; }else if(n > 2) { return Fibonacci(n-1)+Fibonacci(n-2); } return 0; } 使用递归会导致栈溢出 考虑迭代 int Fibonacci(int n ) { // write code here int a = 0; int b = 1; int c = 0; if(n == 1) { return 1; } if(n > 1) { n--; } while(n--) { c = a+b; a = b; b = c; } return c; } 求最大公约数: 碾转相除法 最小的块的问题: int gcd(int a, int b ) { int b_num = 0; int s_num = 0; int num = 0; if(a > b) { b_num = a; s_num = b; }else{ b_num = b; s_num = a; } //int b_num = a > b ? a : b; //int s_num = a < b ? a : b; while(1) { num = b_num % s_num; if(num == 0) { return s_num; } b_num =s_num; s_num = num; } } 判断文字是否为回文字符: bool judge(char* str ) { if(strlen(str) == 1) { return true; } char *p = str; char *q = str+strlen(str)-1; while(p < q) { if(*q != *p) { return false; } p++; q--; } return true; } 链表练习 1、不使用可函数将整数转为字符串 void int2str(int n,char *str) 2、不使用库函数将字符串转换为数字 int str2int(const char *str) #include <stdio.h> #include <stdlib.h> #include <string.h> int str2int(const char *str) { const char *ptr = str; if(*str == '-' || *str == '+') { str++; } int temp = 0; while(*str != '\0') { if(*str < '0' && *str > '9') { break; } temp = temp*10 + (*str-'0'); str++; } if(*ptr == '-') { temp = -temp; } return temp; } int main() { char *num = "123"; int a = str2int(num); printf("the num is %d\n",a); /* Write C code in this online editor and run it. */ printf("Hello, World! \n"); return 0; } 编程实现strcpy函数 char *strcpy(char *strDest,const char *strSrc) { if(strDest == NULL || strSrc == NULL) { return NULL; } char *strDestCopy = strDest; while((*strDest++ = *strSrc++) != '\0'); return strDestCopy; } 编程实现memcpy函数 void *memcpy2(void *memTo,const void *memFrom,size_t size) { assert(memTo != NULL) && assert(memFrom != NULL); char *tempFrom = (char *)memFrom; char *tempTo = (char *)memTo; while(size -- > 0) { *tempTo++ = *tempFrom++; } return memTo; } 变实现字符串中子串的查找 strstr函数的实现 const char *strstr(const char *src,const char* sub) { const char *bp; const char *sp; if(src == NULL || sub == NULL) { return src; } while(*src != '\0') { bp = src; sp = sub; do{ if(!*sp) return src; }while(*bp++ == *sp++) src += 1; } return NULL; } 编程实现字符串中的各单词的翻转 编程实现stcmp库函数 int mystrcmp(const char *src,const char *dst) { int ret = 0; while(!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) { src++; dst++; } if(ret < 0) ret = -1; else if(ret > 0) ret = 1; return (ret); } 编程查找两个子串的最大公共子串 char *commonstring(char *str1,char *str2) { int i ,j; char *shortstr,longstr; char *substr; if(NULL == str1 || NULL == str2) { return NULL; } if(strlen(str1) <= strlen(str2)) { } } tcp/ip协议栈 STL库的使用 多线程管理 tcp/ip,http协议 select,epoll的底层实现 项目介绍: 1、http协议的使用 HTTP是HyperText Transfer Protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程及数据本身的格式 分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接。 这里有几点需要注意, 1、浏览器与Web服务器的连接过程是短暂的,每次连接只会处理一个请求和响应。 2、对于每一个页面的访问,浏览器和Web服务器都会建立一个单独的连接。 3、浏览器和Web服务器之间的所有通讯都是完全独立分开的请求和响应。 这几点对于后面的学习Servlet时对于Servlet的理解很重要。 我们这里用firefox带的开发者选项中的浏览器控制台可以查看一次请求时,Http协议的具体数据。 这里分别可以看到我们这次请求的网址和请求的方式,以及采用的Http协议的版本是HTTP/1.1和返回的状态码。 浏览器请求数据的方式有很多种,最常见的就是GET和POST两种请求方式。 GET请求方式有如下特点: 1、GET请求方式是直接在URl地址后面以?的形式带数据给浏览器,多个数据之间是以&来间隔的。例如:GET/mail/1.html?name=abc&password=xyz HTTP/1.1 2、GET请求方式后面带的数据大小是有限制的,一般不超过1K。 POST请求方式的特点 1、POST请求方式是在 请求的正文中传递数据。 2、这种方式传递的数据大小是没有限制的。 接下来介绍一下状态码:浏览器每一次向服务器发送请求,Web服务器对各种请求的有着不同的处理方式。 状态码就反应服务器对浏览器请求作出的响应的具体细节。 一个完整的HTTP请求包括如下内容:一个请求行、若干消息头、以及请求正文,其中的一些消息头和正文都是可选的,消息头和正文内容之间要用空行隔开。 互斥锁和条件变量 线程锁和条件变量 互斥量是用来给资源上锁的,而条件变量是用来等待而不是用来上锁的 条件变量用来自动阻塞一个线程,直到特殊情况发生为止 int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr); int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex); int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime); int pthread_cond_destory(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); pthread_cond_wait() 1、线程放在等待队列上,解锁 2、等待pthread_cond_signal信号后去竞争锁 3、若竞争到互斥锁则加锁 class MyString { public: MyString(char *s) { str = new char[strlen(s)+1]; strcpy(str,s); } ~MyString() { delete []str; } MyString *opretor+(MySring &str); private: char *str; } MyString::MySring *opretor+(MySring &str) { M_str = new char[strlen()] }
刷题记录log
最新推荐文章于 2024-06-13 23:45:11 发布