文本文件记录了用户搜索信息,找到前top 10信息

 

一个文本文件,文件很大,记录了用户搜索关键词,按照搜索时间写进文本,要求统计出其中最频繁出现的前10个词,请给出思想。

  1. 建立Trie树,记录每颗树的出现次数,O(n*le); le:平均查找长度

  2. 维护一个10的小顶堆,O(n*lg10);

  3. 总复杂度: O(n*le) + O(n*lg10);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define WORD_NUM          256
struct trie_node {
	struct trie_node *node[WORD_NUM];
	int value;
	int count;
};
 
struct heap_node {
	char *word;
	int count;
};
 
void adjust_heap(struct heap_node *h, int len, int pos);
void create_heap(struct heap_node *h, int len);
void heap_sort(struct heap_node *h, int len);
int heap_insert_node(struct heap_node *h, int len, struct heap_node n);
void heap_insert_word(struct heap_node *h, int len, char *word, int count);
void destroy_heap(struct heap_node *h, int len);
void show_top_ten_word(struct heap_node *h, int len);
 
struct trie_node *create_trie_node(int value);
int trie_insert_word(struct trie_node *root, unsigned char *word);
void destory_trie_tree(struct trie_node *root);
 
void adjust_heap(struct heap_node *h, int len, int pos)
{
	int r, l, mark;
 
	l = 2 * pos;
	r = l + 1;
	mark = pos;
	if (l >= len) {
		return;
	}
 
	if ( h[mark].count > h[l].count) {
		mark = l;
	}
	if (r < len && h[mark].count > h[r].count) {
		mark = r;
	}
	if (mark != pos) {
		struct heap_node tmp;
		tmp = h[mark];
		h[mark] = h[pos];
		h[pos] = tmp;
		adjust_heap(h, len, mark);
	}
}	
 
void create_heap(struct heap_node *h, int len) 
{
	int range = len / 2;
	
	while (range >= 0) {
		adjust_heap(h, len, range--);
	}
}
 
void heap_sort(struct heap_node *h, int len) 
{
	struct heap_node n;
	create_heap(h, len);
	while (len > 0) {
		len--;
		n = h[len];
		h[len] = h[0];
		h[0] = n;
		adjust_heap(h, len, 0);
	}
}
 
void heap_insert_word(struct heap_node *h, int len, char *word, int count) 
{
	struct heap_node n;
	int size = strlen(word) + 1;
	n.word = malloc(size);
	n.count = count;
	memcpy(n.word, word, size);
	if (heap_insert_node(h, len, n) != 0) {
		free(n.word);
	}
}	
 
/* 不需要插入堆中和已经存在堆中 return -1, 插入返回 0 */
int heap_insert_node(struct heap_node *h, int len, struct heap_node n)
{
	int i;
	if (h[0].count > n.count) {
		return -1;
	}
	
	for (i = 0; i < len; i++) {
		if (strcmp(h[i].word, n.word) == 0) {
			h[i].count = n.count;
			break;
		}
	}
	if (i == len) {
		free(h[0].word);
		h[0] = n;
		adjust_heap(h, len, 0);
		return 0;
	}
	else {
		adjust_heap(h, len, i);
		return -1;
	}
}
void destroy_heap(struct heap_node *h, int len)
{
	while (len > 0) {
	   free(h[--len].word);
	}
	free(h);
	h = NULL;
}	
 
void show_top_ten_word(struct heap_node *h, int len)
{
	int i;
	heap_sort(h, len);
	for (i = 0; i < len; i++) {
		printf("%-8d %s\n", h[i].count, h[i].word);
	}
}
 
struct trie_node *create_trie_node(int value)
{
	struct trie_node * node = calloc(1, sizeof(struct trie_node));
	node->value = value;
	return node;
}
int trie_insert_word(struct trie_node *root, unsigned char *word) 
{
	struct trie_node *n;
	while (*word != 0) {
		n = root->node[*word];
		if (n == NULL) {
			n = create_trie_node(*word);
			root->node[*word] = n;
		}
		root = n;
		word++;
	}
	root->count++;
	return root->count;
}
void destroy_trie_tree(struct trie_node *root) 
{
	int i;
	if (root == NULL) {
		return;
	}
	for (i = 0; i < WORD_NUM; i++) {
		destroy_trie_tree(root->node[i]);
	}
	free(root);
}
 
int main(int argc, char *argv[])
{
	FILE *fp;
	struct trie_node *root;
	struct heap_node *h;
	int heap_len;	
	char line[1024];
	if (argc != 2) {
		return 0;
	}
 
	root = malloc(sizeof(struct trie_node));
	heap_len = 10;
	h = calloc(heap_len, sizeof(struct heap_node));
 
	fp = fopen(argv[1], "r");
	if (fp == NULL) {
		return 0;
	}
	int start = 0;
	while (fgets(line, sizeof(line), fp)) {
		int count;
		int word_len = strlen(line) - 1;
		line[word_len] = 0;
		count = trie_insert_word(root, (unsigned char *) line);
		if (start < heap_len) {
			int i;
			for (i = 0; i < start; i++) {
				if (strcmp(h[i].word, line) == 0) {
					h[i].count = count;
					break;
				}
			}
			if (i == start) {
				h[start].word = malloc(word_len);
				memcpy(h[start].word, line, word_len);
				h[start].count = count;
				start++;
				create_heap(h, start);		
			}
		}
		else {
			heap_insert_word(h, heap_len, line, count);
		}
 
	}	
	fclose(fp);
	heap_len = start;
	show_top_ten_word(h, heap_len);
	destroy_heap(h, heap_len);
	destroy_trie_tree(root);
	return 0;
}

原文

以下是OWASP Top 10漏洞的防御方法: 1. 注入(Injection) - 使用参数化查询和存储过程来防止SQL注入 - 对用户输入进行输入验证和过滤,确保只接受预期的数据类型和格式 2. 破解认证和会话管理(Broken Authentication and Session Management) - 实现强密码策略,包括密码长度、复杂度和更新周期 - 使用多因素身份验证来加强认证 - 使用安全的会话管理技术,如加密会话ID、限制会话超时时间和强制重新认证等 3. 跨站脚本攻击(XSS,Cross-Site Scripting) - 对用户输入进行输入验证和过滤,确保只接受预期的数据类型和格式 - 对输出进行HTML编码,确保所有用户输入都被视为纯文本而不是HTML代码 4. 不安全的直接对象引用(IDOR,Insecure Direct Object References) - 隐藏内部实现细节,如使用UUID而不是自增ID - 对敏感数据进行访问控制,确保只有授权的用户才能访问 5. 安全配置错误(Security Misconfiguration) - 定期审查应用程序配置和服务器配置,确保按照最佳实践进行配置 - 更新和修补软件和组件,避免使用已知的漏洞和弱点 6. 敏感数据泄露(Sensitive Data Exposure) - 使用加密技术来保护敏感数据,如使用HTTPS来保护数据传输,使用加密算法来保护存储数据 - 不要将敏感数据存储在不安全的地方,如客户端缓存、日志文件或非加密的数据库 7. 缺乏访问控制(Lack of Access Control) - 实施强大的访问控制机制,确保只有授权的用户才能访问敏感资源 - 对每个用户进行身份验证和授权,确保他们只能访问他们需要的资源 8. 跨站请伪造(CSRF,Cross-Site Request Forgery) - 使用同步令牌来验证每个请的来源,确保请来自合法的用户和会话 - 在URL参数中包含随机值,防止请被预测和复制 9. 使用已知漏洞的组件(Using Components with Known Vulnerabilities) - 定期更新和升级软件和组件,避免使用已知的漏洞和弱点 - 使用漏洞扫描工具来检测和识别组件漏洞 10. 不足的日志记录和监控(Insufficient Logging and Monitoring) - 记录所有的安全事件和异常,包括登录失败、访问拒绝和恶意行为 - 实现实时监控和警报机制,对安全事件和异常进行实时响应和处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值