当前位置:文档之家› 统计数字与字典序问题

统计数字与字典序问题

1、问题一:
【①问题描述】
一本书的页码从自然数1 开始顺序编码直到自然数n。

书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。

例如,第6页用数字6表示而不是06或006等。

数字计数问题要求对给定书的总页码n计算出书的全部页码中分别用到多少次数字0、1、2、 (9)
【②问题分析】
给定表示书的总页码的10 进制整数n (1≤n≤109) 。

编程计算书的全部页码中分别用到多少次数字0、1、2、 (9)
【③算法设计】
将页码数除以10,得到一个整数商和余数,商就代表页码数减余数外有多少个1—9作为个位数,余数代表有1—余数本身这么多个数作为剩余的个位数。

此外,商还代表1—商本身这些数出现了10次,余数还代表剩余的没有计算的商的大小的数的个数。

把这些结果统计起来即可。

【④算法实现】
#include "stdio.h"
void main()
{
int i,a[10];
long data,j,k;
scanf("%ld",&data);
for(i=0;i<10;i++)
{
a[i]=0;
}
for(j=data;j>0;j--)
{
k=j;
while(k>0)
{
i=k%10;
a[i]++;
k=k/10;
}
}
for(i=0;i<10;i++)
{
printf("%d\n",a[i]);
}
return 0;
}
【⑤测试数据】
输入:11
【⑥运行结果】
2、问题二
【①问题描述】
在数据加密和数据压缩中常需要对特殊的字符串进行编码。

给定的字母表A 由26 个小写英文字母组成A={a,b,…,z}。

该字母表产生的升序字符串是指字符串中字母按照从左到右出现的次序与字母在字母表中出现的次序相同,且每个字符最多出现1 次。

例如,
a,b,ab,bc,xyz 等字符串都是升序字符串。

现在对字母表A 产生的所有长度不超过6 的升序
1 2 …26 27 28 …
a b …z ab ac …
对于任意长度不超过6 的升序字符串,迅速计算出它在上述字典中的编码。

【②问题分析】
考察一般情况下长度不超过k的升序字符串。

设以第i个字符打头的长度不超过K 升序字符串个数为f(i,k),长度不超过K的升序字符
总个数为g(k),则g(k) = ∑-
=
k
i
k
i
f
27
1
)
,(
,以第i个字母开头的长度为1的字符串有一个。

即:
f(i,1)=1
长度1的升序字符串分别是:a,b,c,d,…,x,y,z。

共26个。

即:
g(1)= ∑-
=
1
27
1
)1,(
i
i
f
=26。

【③算法设计】
数据输入:输入数据由文件名为input.txt的文本文件提供。

文件的第一行是一个正整数k,表示接下来共有k行。

接下来的k 行中,每行给出一个字符串。

结果输出:将计算结果输出到文件output.txt中。

文件共有k 行,每行对应于一个字符串的编码。

【④算法实现】
#include<cstdio>
#include<string.h>
#include<iostream>
using namespace std;
int a[27][7]={0};
void InitComponent();//初始化组合数a[i][j]表示C(i,j)
int IsValidate(char c[]);//判断读入的字符串是否升序
int main() {
int n,strln,result;
int i,j,k;
char str[7];
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
InitComponent();
cin>>n;
while(n--)
{
cin>>str;
if(!IsValidate(str))
{
cout<<"invalid!\n"; continue;
} result=1;
strln=strlen(str);
for(j=1;j<strln;j++)//步骤(1)
result+=a[26][j];
for(i=0;i<str[0]-'a';i++)//步骤(3)
result+=a[26-1-i][strln-1];
for(k=1;k<strln;k++)//步骤(4)(5)(6)类似步骤(3)
{
for(i=str[k-1]-'a'+1;
i<(int)str[k]-'a';i++)
{
result+=a[26-i-1][strln-k-1];//第一次错误地写成[26-i] }
}
cout<<str<<"\t"<<result<<endl;
} return 0;
}
void InitComponent()//初始化组合数a[i][j]表示C(i,j)
{
int i,j,k;
for(i=26;i>=0;i--)
{
a[i][0]=1;
a[i][1]=i;
k=i+1;
for(j=2;j<7;j++)
{
if(j>i)break;
a[i][j]=a[i][j-1]*(k-j)/j;
}
}
}
int IsValidate(char c[])//判断读入的字符串是否升序
{
int len=strlen(c),i;
for(i=0;i<len-1;i++)
{
if(c[i]>=c[i+1])
return 0;
}
return 1;
}
【⑤测试数据】
输入:
2
a
ab
【⑥运行结果】。

相关主题