数组使信息有序化

当题目中的数据缺乏规律时,很难把重复的工作抽象成循环不变式来完成,但先用数组结构存储这些地信息后,问题就迎刃而解。

一、编写算法将数字编号翻译成英文编号

1.问题描述

例:将35706“翻译”成 英文编号three-five-seven-zero-six。

2.思路分析

(1)思路一

1) 编号一般位数较多,可按长整型输入和存储。
2) 将英文的“zero——nine”存储在数组中,对应下标为0——9。这样无数值规律可循的单词,通过下标就可以方便存取、访问了。
3) 通过求余、取整运算,可以取到编号的各个位数字。用这个数字作下标,正好能找到对应的英文数字。
4) 考虑输出翻译结果是从高位到低位进行的,而取各位数字,比较简单的方法是从低位开始通过求余和整除运算逐步完成的。所以还要开辟一个数组来存储从低位到高位翻译好的结果,并记录编号的位数,最后倒着从高位到低位输出结果。

(2)思路二

编号按字符串类型输入,更符合实际的需求:
1) 用数值类型是无法正确的存储以0开头的编号,如编号“00001”若按数值类型存储,只能存储为1;
2) 按字符串处理编号可以方便的从左到右(从高位到低位)进行,与输出过程相符合,不需要开辟数组存储翻译结果;
3) 不需要通过算术运算来取编号的个位数字。
4) 由字符串中取出的“数字”编号是字符型,根据字符’0’的ASCII值为48,则"字符-48"就是字符所对应的数字值,用它作下标就可完成翻译工作。

3.伪码描述

(1)思路一的伪码

main( )
 {
    int i,a[10], ind;    
    long num1,num2;
    char eng[10][6]={“zero”,”one”,”two”,”three ”,” four”,” five”,”six”,”seven”,“eight”,”nine”};
    print(“Input a num”);
    input(num1);    
    num2=num1;  
    ind =0;
    while (num2<>0)
    {
        a[ind]=num2 mod 10;  
        ind= ind +1;  
        num2=num2/10; 
    }
    print(num1, “English_exp:, eng[a[ind-1]]);
    for( i=ind-2;i>=0;i=i-1)
        print(-”,eng[a[i]]);
} 

(2)思路二的伪码

main()
{
    int i=0,n;
    char num[40];
    char eng[10][6]={“zero”,”one”,”two”,”three ”,” four”,” five”,”six”,”seven”,“eight”,”nine”};
    print(“Input a num”);
    input(num1); 
    n=strlen(num);//取字符串的长度
    if(n=0) 
    {
        print("input error!");
    } else 
    {
        print(num,"English_exp:",eng[num[0]-48]);
        for(i=1;i<=n-1;i++) 
        {
            print("-",eng[num[i]-48]);
        }
    }
}

4.算法的说明

把数值类型的数据按字符串存储的技巧,还可以在高精度数据计算等问题上灵活运用。

二、售货员给顾客找零钱问题

1.问题描述

一个顾客买了价值x元的商品,并将y元的钱交给售货员。 售货员希望用张数最少的钱币找给顾客。

2.思路分析

无论买商品的价值x是多大,找给他的钱最多需要以下六种币值:50,20,10,5,2,1。
1)为了能达到找给顾客钱的张数最少,先尽量多地取大面额的币种,由大面额到小面额币种逐渐进行。
2)六种面额不是等差数列(无步长),为了能构造出循环不变式,将六种币值存储在数组B。这样,六种币值就可表示为B[i],i=1,2,3,4,5,6。为了能达到先尽量多地找大面额的币种,六种币值应该由大到小存储。
3)另外还要为统计六种面额的数量,同样为了能构造出循环不变式,设置一个有六个元素的累加器数组S,这样操作就可以通过循环顺利完成了。

3.伪码描述

main( )
{
    int  i,j,x,y,z,a,b[7]={0,50,20,10,5,2,1},s[7];
    input(x,y);
    z=y-x;
    for(i=1;i<=6;i=i+1)
     {
        a=z/b[i];    
        s[i]=s[i]+a;      
        z=z-a*b[i];
    }
    print(y,-”x,=,z:);
    for(i=1;i<=6;i=i+1)
        if (s[i]<>0)
            print(b[i],----, s[i]);
} 

4.算法的说明及分析

1)每求出一种面额所需的张数后,一定要把这部分金额减去: “y=y-A*B[j];”,否则将会重复计算。
2)算法无论要找的钱z是多大,我们都从50元开始统计,所以在输出时要注意合理性,不要输出无用的张数为0
的信息。
3)问题的规模是常量,时间复杂性肯定为O(1)

发布了28 篇原创文章 · 获赞 13 · 访问量 448

猜你喜欢

转载自blog.csdn.net/yo_u_niverse/article/details/105531889