1-2 字典序问题——分治

问题描述:
在这里插入图片描述

1算法思路
  • 编码=长度小于len的字符串个数+长度等于len,但在所给字符串之前的字符串个数
  • 长度小于len的字符串个数=长度为1,2,3…len-1的升序字符串个数之和
  • 长度为n的升序字符串个数 =分别以26个字母开头,长度为n的字符串个数之和
  • 以i开头的、长度为n的升序字符串个数=以剩下字母依次开头,长度为n-1的升序字符串个数
2程序代码
#include<bits/stdc++.h>
using namespace std;
#include<windows.h>
#define N 10
int k;
char a[N];
//计算以begin开头的、长度为n的升序字符串个数 
int s_1(int begin,int n){
	int s=0;
	if(n==1) return 1;
	else{
		for(int i=begin+1;i<=26;i++){
			s+=s_1(i,n-1);
		}
	}
	return s;
}
//计算长度为n的升序字符串个数 
int s_2(int n){
	int s=0;
	for(int i=1;i<=26;i++){
		s+=s_1(i,n);
	}
}
int main()
{
	freopen("input.txt","r",stdin);//输入数据由文件名为input.txt的文本文件提供
	freopen("output.txt","w",stdout);//将计算结果输出到文件output.txt
    //用于记录时间
    LARGE_INTEGER nFreq,nBegin,nEnd;
	QueryPerformanceFrequency(&nFreq);	
	QueryPerformanceCounter(&nBegin);
    //算法核心代码如下
	scanf("%d",&k);
	while(k--){
		scanf("%s",&a);
		int ans=0;
		int len=strlen(a);
		//第一步:计算长度小于len的字符串个数
		for(int i=1;i<len;i++){
			ans+=s_2(i);
		}
		//第二步:加上长度等于len,但在所给字符串之前的字符串个数
		int temp=0;
		for(int i=0;i<len;i++){
			int num=a[i]-'a'+1; //获取当前字符顺序号
			int len_2=len-i; //获取当前字符串长度
			for(int j=temp+1;j<num;j++){
				ans+=s_1(j,len_2);
			} 
			temp=num; //保证升序
		}
		 printf("%d\n",ans+1);
	}
	fclose(stdin);
    fclose(stdout);
    
	QueryPerformanceCounter(&nEnd);
	double t=(double)(nEnd.QuadPart-nBegin.QuadPart)/(double)nFreq.QuadPart; 
	printf("运行时间:%lf",t);
	return 0;
}
3生成三种不同规模的测试数据:小、中、大(e.g.,几个、几百个、几万个甚至更多)
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;

int count=10;
	
int main(){	
	freopen("input.txt","w",stdout);
	printf("%d\n",count);
	srand(time(0));
	for(int j=0;j<count;j++)
	{
		int x=0,A=26,pre=0,n=6;
	
		for(int i=1;i<=n && x!=26;i++){
			x=rand()%A+1;
			x=x+pre;
			pre=x;
			A=26-x;
			printf("%c",'a'+x-1);
		}
		printf("\n");
	}
	fclose(stdout);
	return 0;
}
4不同规模数据实验的时间对比
数据规模n101000100000
运行时间/s0.0035120.62852240.902037
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值