Contact

题意:有一串仅包含0和1的字符串(最长为200,000),统计长度在[A, B]的模式出现的次数(1<=A, B<=12),并将出现次数前N(1<=N<=50)的模式打印。长度为2的模式有00,01,10,11。


解题思路

  1. 用一个树来表示字符串,左子树表示0,右子树表示1。类似Trie树。字符串用根节点到某一节点的路径来表示,如第三层最左边的字符串代表000,第三层第二个字符串代表001。因为最长的模式有12个字符,那么这棵树最多有13层,总结点数最多为2^13-1 = 8191个,所以这个完全二叉树可以由一个数组tree来表示,tree[i] = j代表i号节点代表的模式出现过j次。如果我没讲清楚可以搜索“Trie树”。
  2. 对[A, B]长度进行遍历,针对某一长度len,从头遍历一遍主串s,并将找到的s[i....i+len-1]转换为tree中相应的节点index。这个index初始化为0,遍历找到的s[i ... i+len-1],如果字符为0则index = index * 2 + 1,如果字符为1则index = index * 2 + 2。最终将tree[index]++。
  3. 遍历完后这个tree数组中存储的就是长度在[A, B]中的每种模式出现的次数。
  4. 对tree进行后续的处理即可输出最后的结果,逻辑不难,就是有点繁琐,在此不赘述。我用的是最简单的查找方式,因为需要的N不是很大,所以最终时间是够的。

代码

/*
ID: zc.rene1
LANG: C
PROG: contact
*/

#include<stdio.h>
#include<string.h>

void PrintNum(int num, FILE *fout)
{
    char s[13];
    int index = 0, i;

    memset(s, 0, 13*sizeof(char));

    while (num != 0)
    {
	if (num % 2 == 0)
	{
	    s[index++] = '1';
	    num = (num - 1) / 2;
	}
	else
	{
	    s[index++] = '0';
	    num = num / 2;
	}
    }
    
    for (i=index-1; i>=0; i--)
    {
	fprintf(fout, "%c", s[i]);
    }
}
int main(void)
{
    FILE *fin, *fout;
    char main_string[200000];
    int tree[8192];
    int has_visited[8192];
    int pow_of_two[14];
    int A, B, N, index = 0;
    int i, j, len, temp_index;

    fin = fopen("contact.in", "r");
    fout = fopen("contact.out", "w");

    /*get input*/
    fscanf(fin, "%d %d %d", &A, &B, &N);
    memset(main_string, 0, 200000*sizeof(char));
    while (fscanf(fin, "%s", main_string + index) != EOF)
    {
	index = strlen(main_string);
    }
    /*generate tree*/
    memset(tree, 0, 8192*sizeof(int));
    for (len=A; len<=B; len++)
    {
	for (i=0; i<=(index-len); i++)
	{
	    temp_index = 0;
	    for (j=0; j<len; j++)
	    {
		if (main_string[i+j] == '0')
		{
		    temp_index = temp_index * 2 + 1;
		}
		else
		{
		    temp_index = temp_index * 2 + 2;
		}
	    }
	    tree[temp_index]++;
	}
    }
    /*generate pow(2, n)*/
    pow_of_two[0] = 1;
    for (i=1; i<=13; i++)
    {
	pow_of_two[i] = (pow_of_two[i-1] * 2);
    }
    /*print the result*/
    int has_print = 0;
    memset(has_visited, 0, 8192*sizeof(int));
    while (has_print < N)
    {
        int temp_max = -1;
	for (i=pow_of_two[A]-1; i<=pow_of_two[B+1]-2; i++)
	{
	    if ((has_visited[i] == 0) && (tree[i] > temp_max))
	    {
		temp_max = tree[i];
	    }
	}
	if (temp_max <= 0)
	{
	    break;
	}
	int temp_count = 0;
	for (i=pow_of_two[A]-1; i<=pow_of_two[B+1]-2; i++)
	{
	    if (tree[i] == temp_max)
	    {
		has_visited[i] = 1;
		if (temp_count == 0)
		{
		    fprintf(fout, "%d\n", temp_max);
		    PrintNum(i, fout);
		    temp_count++;
		}
		else if (temp_count % 6 == 0)
		{
		    fprintf(fout, "\n");
		    PrintNum(i, fout);
		    temp_count++;
		}
		else
		{
		    fprintf(fout, " ");
		    PrintNum(i, fout);
		    temp_count++;
		}
	    }
	}
	fprintf(fout, "\n");
	has_print++;
    }
    return 0;
}
































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Hive中,contact是一个API中的方法或者函数。根据引用所提到的目录,可能存在一些与contact相关的方法,如client.new_contact、client.update_contact、client.contacts_tags和client.contacts_subscribers。这些方法可能用于处理联系人信息和标签。除此之外,引用和引用中也提到了一个concat函数,它可以用来拼接字符串类型的数据。例如,concat(aa, ':', bb)可以将aa列和bb列用冒号连接起来,形成aa:bb的结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [wix-hive-ruby:Wix Hive API 的 Ruby 接口](https://download.csdn.net/download/weixin_42133415/19644398)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [hive中的contact,concat_ws,collect_set(),explode实现行列互转](https://blog.csdn.net/jsbylibo/article/details/82859168)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [hive中的拼接函数contact,concat_ws,collect_set()及explode(),lateral view函数](https://blog.csdn.net/shuyun123456789/article/details/104726756)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值