Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2341573
  • 博文数量: 816
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 5010
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-17 17:57
文章分类

全部博文(816)

文章存档

2011年(1)

2008年(815)

分类:

2008-12-17 18:06:11

小生刚工作,正学习VC++,在工作时遇到一个问题,希望高手帮忙!
  问题:
      输入两段字符串,8位,分别为起始段和终止段,比如:aaaaaaaa ---zzzzzzzz,然后任意输入一个分段数字n,比如5,就可分成等份的5段。关于分段算法我是这样写的:
         char a[8]={'a','a','a','a','a','a','a','a'};     //为方便,暂且做初始化处理了
char b[8]={'z','z','z','z','z','z','z','z'};
int i,j;
         float m,totalcount=1;

for(i=0;i<8;i++)                    //计算所有种类
{
             totalcount=totalcount*(b[i]-a[i]+1);    
}
  printf("Please Input duan dian:");
scanf("%d",&n);
m=(int)(totalcount/n);
          printf("%f %d",totalcount,m);

 我想算出分段出的每段长度m,可结果和实际不符,不知道到底错在哪里了?
 如果要算出具体的几个分段点,又该如何做?
                   拜求高手现身啊!在线等答案!

--------------------next---------------------
/*
首先的问题就是很多情况下无法完全平均等分,可能会有一些误差。

主要的问题是速度上,我采用的方法比较笨,就是计算出来那个totalcount,然后算出每段的长度m,接下来就是从起始段开始数,
数m个,然后就打印出来这个分段值,然后再数m个,再打印下一个分段值……

但是从aaaaaaaa-zzzzzzzz一共有208827064576个数,所以int是不能够胜任了,c++中int是4字节,最大表示4294967296,所以应该
使用long long型或者__int64型,但是已经没有什么意义了,因为这个算法太慢了,如果真的要分出来aaaaaaaa-zzzzzzzz不知道要
等到什么时候了。

如果你有了比较好的算法也告诉我一声。
*/

#include
#include
main()
{
    char a[9];  //记录起始段
    char b[9];  //记录中止段
    char c[9],d[9];  //保存中间值将要使用的量

    unsigned int i,j;
    unsigned int k,n;  //记录分为几段
    unsigned int m;  //每段的长度
    unsigned int totalcount=1;
    cout<<"输入8位起始段:";

    for(i=0;i<8;i++)
        cin>>a[i];
    a[i]='\0';

    cout<<"输入8位中止段:";
    for(i=0;i<8;i++)
        cin>>b[i];
    b[i]='\0';

    //循环将b[]赋值给c[]
    for(i=0;i<9;i++)
        c[i]=a[i];

    //循环完成所有种类的计算
    for(i=0;i<8;i++)
    {
        totalcount=totalcount*(b[i]-a[i]+1);
    }

    printf("Please Input duan dian:");
    scanf("%d",&n);

    m=totalcount/n;
    k=0;
    while(k++    {
        //循环将c[]赋值给d[],原因是打印时方便
        for(i=0;i<9;i++)
            d[i]=c[i];

        //这个循环是对每段进行计算
        for(i=0;i        {
            c[7]++;

            //这个循环完成进位运算
            for(j=7;j>0;j--)
                if(c[j]>b[j])
                {
                    c[j-1]++;
                    c[j]=a[j];
                }
        }
        if(k            cout<        else
            cout<    }
    system("Pause");
}

--------------------next---------------------
guohao,
  我用的是VC,现在可以运行了,但结果不是令人满意!你看看啊,如果我输入的是8个a和8个z,如:aaaaaaaa--zzzzzzzz,然后输入分段的数字,比如5,结果 开头字母都是a,最后一行从a突然到了z,这和实际不符啊。怎么办?给数字分段还行。
  有人说我的那个算法不行,因为如果碰到的字符串里有大小写混合的话,结果算出的排列总数必然不对,他给了我另一个公式计算总排列的数目,如下:
         为简单起见,假设输入的字符串是 aBc  和 BcD,因为是大小写混合,是52进制,则总数为:(B-a)*52*52+(c-B)*52+(D-c)+1,减去中间的一些特殊字符,为总数?不知道他这中算法准不准确?望给出解答。

  我的原题目大意为:
       任意输入8位的字符串,它们可以是大写字母、小写字母,或者是大小写字母的组合,用他们做开始断和终止端,把他们之间出现的任意一个字符串进行分段处理,段数任意分,每段可以不均等,但不可漏掉一个值。
   我的想法和你一样,用总数除以段数,就得每段的长度,然后加上开始段,就为第一个分段的末尾值,依次类推!但用那个求总数的公式时,总数算出来结果和实际差不了多少,但除以段数就差大了,7位以前的可以,8位不行,我的总数设的是实型,段数为整形,结果强制转换成整形,为何结果就差好多了呢?  

--------------------next---------------------
如果是你那个公式:(B-a)*52*52+(c-B)*52+(D-c)+1的计算方法的话,那么又要回到刚开始我问你的那个问题了bbbbbbbf的下一个是什么,到底是bbbbbbbg还是bbbbbbcb,你一定要想清楚,因为你的算法:(B-a)*52*52+(c-B)*52+(D-c)+1说明答案是前者,而我写的答案是后者(虽然这个算法也有很大问题,但是首先要弄清的问题是哪一种是题目的要求)。

当然,你写的这个算法也有很大问题,B-a是什么,B的ASCII码是66,而a的ASCII码是98,那么B-a=-32,这又是什么意思呢。

现在的关键就是bbbbbbbf的下一个是不是bbbbbbcb,这个确定了才能确定正确的算法,你好好考虑一下。

从题目的意思上来看,我认为bbbbbbbf的下一个应该是bbbbbbbg,因为题目是说对字符串进行分段处理。我对题目的理解是这样的:

举例1:写出bbbbbbbb-ffffffff的所有字符串(为方便起见,暂不考虑大写字母):

bbbbbbbb,……,bbbbbbbf,bbbbbbbg,……,bbbbbbbz,bbbbbbca,……,bbbbbbcz,bbbbbbda,……,ffffffez,fffffffa,……,ffffffff。

你一定要考虑清楚了,因为这样比较合理,也更符合题目的要求。

举例2:例如ab~ba才可以计算,因为他包含ab,ac,ad,ae,……,az,ba,也才存在所谓的进制问题。

我不知道我说清楚没有,你仔细看看我举的两个例子,如果bbbbbbbf的下一个是bbbbbbcb,那么ab~ba是无法计算的,因为你必须保证中止段的字符串中的每个字符都要比相对应的起始段的字符串中的每个字符都要大!

--------------------next---------------------


 恩,我确实没把问题搞透,现整理如下:
  有张编号0--95的字符表,对应的字符是0、1、2……键盘上95个可见字符,现在开始端和终止端任意输入8个字符(都是表里的字符),对两段之间的出现的任何字符进行等份处理,输出分段的结果,每段长度允许有重合字符,但不能有漏值。
这个求分段的算法该如何设计,因为涉及到进制的问题。
   
  举例如下:
      为简单起见,设字符3位                                                       *     *    *
    第一位有字符 0、1、2、a、b、c共6个字符,                                      0     3    5
                                                                                  1     5    6
    第二位有3、5、d、e 共4个字符,                                                2     d    f
    第三位有5、6、f、g、h 共5个字符。                                             a     e    g
                                                                                  b          h
    现在输入开始端:035,终止端1ef,                                              c
                                           
  因为开始端 0和终止端 1都在第一位,所以之间的差距就是(1-0)=1个长度,
             3、4都在第二位,差距就是(e-3)=3个长度,
             5、f都在在第三位,差距为(f-5)=2个长度,
    所以总的排列数目为: (6*1)*(4*3)*(5*2),如果要搜索的开始与终止字符不在同一位上时,又涉及到进制的问题,
  这可难到了我,算发给如何实现比较好?
   
 
guohao兄,有QQ吗?加我吧,271042507,我想向你请教请教

--------------------next---------------------
#include "stdafx.h"
#include
#include
#include

int Count(int,int,int);


int Count(int x,int y,int k)
{
    int i;
    int z=y-x;
    for(i=0;i        z=z*3;
    return z;
}
int main(int argc, char* argv[])
{
bool TheEnd=true;
    int i,j,k;
    int along,n;
    int iStart[8],iEnd[8],iMid[10][8];
    int total=0;
    int mod[8];
    n=3;
    char a[8][3]={
                  {'f','g','8'},
                  {'9','0','4'},
                  {'b','5','h'},
                  {'3','c','a'},
                  {'w','9','7'},
                  {'3','2','y'},
                  {'a','3','b'},
                  {'1','7','9'}
                 };
    char start[9]="f9bcw3a1";
    char end[9]="g45cw3a1";
    for(i=0;i<8;i++)
    {
        for(j=0;j<3;j++)
        {
            if(a[i][j]==start[i])
                iStart[i]=j;
            if(a[i][j]==end[i])
                iEnd[i]=j;
        }
    }
    for(i=0;i<8;i++)
        total+=Count(iStart[i],iEnd[i],i);
    total++;
    along=total/n;
    for(i=0;i<8;i++)
    {
        mod[i]=along%3;
        along/=3;
        //cout<    }
    for(i=0;i<8;i++)
    {
        iMid[0][i]=iStart[i]+mod[i];
        if(iMid[0][i]>=3)
        {
            iMid[0][i]-=3;
            iMid[0][i+1]++;
        }
    }
    iMid[0][0]--;
    for(i=1;i<=n;i++)
    {
        for(j=0;j<8;j++)
        {
            iMid[i][j]=iMid[i-1][j]+mod[j];
            if(iMid[i][j]>=3)
            {
                iMid[i][j]-=3;
                iMid[i][j+1]++;
            }
        iMid[i][0]--;
        }
    }
    for(i=0;i    {
        for(j=0;j<8;j++)
        {
            k=iMid[i][j];
            cout<        }
        cout<    }
    for(i=0;i<8;i++)
    {
        k=iMid[n-1][i];
        if(a[i][k]!=end[i])
        {
            TheEnd=false;
            break;
        }
    }
    if(!TheEnd)
    {
        for(i=0;i<8;i++)
        {
            k=iMid[n][i];
            cout<        }
        cout<    }
   
return 0;
}


和你上次说的一样,输出有些问题,问题出在哪?
代码能不能改成任意输入8位字符串的形式?



--------------------next---------------------
/*
程序的算法基本没有什么问题,但是不够灵活,这个比较容易修改,比如n的值是可以改变的,由键盘输入,
起始字符串和终止字符串也可以由键盘输入,此程序只是为了调试方便,所以还未修改。

处理大表时程序也需要修改,比如98×8的表要将int修改为long long。

程序的进制数只做了3进制的调试,如果是其它进制,比如98,那么需要修改很多地方,可以用宏定义来代替
实际数值,这样更加合理。

输出包括所有分段点和终止字符串,但是不输出初始字符串。

程序只是调试使用,还没有完善,很多地方需要修改。
*/
#include
int Count(int,int,int);

int main(void)
{
    bool TheEnd=true; //因为不知道是否能够平均分配,用TheEnd来判断,TheEnd为false时无法平均分。
    bool Carry=false;  //用来进行进位的标识,当Carry为true时需进位。
    int i,j,k;
    int total=0;  //记录总长度
    int n,along;  //记录分段数和每段的长度
    int iStart[8],iEnd[8],iMid[10][8];  //前两个变量记录起始字符串和终止字符串在表中的位置,最后一个变量记录分段点的位置
    int mod[8];  //进制转换时需要用到的变量
    n=5;

    //  将表输入到这个数组,按照由低位到高位的顺序
    char a[8][3]={
                  {'f','g','8'},
                  {'9','0','4'},
                  {'b','5','h'},
                  {'3','c','a'},
                  {'w','9','7'},
                  {'3','2','y'},
                  {'a','3','b'},
                  {'1','7','9'}
                 };

    char start[9]="f9bcw3a1";  //初始化起始字符串和终止字符串,从低位到高位排列
    char end[9]="g45cw3a1";

    //这个循环完成记录起始字符串和终止字符串在表中的位置
    for(i=0;i<8;i++)
    {
        for(j=0;j<3;j++)
        {
            if(a[i][j]==start[i])
                iStart[i]=j;  //将起始字符串的位置记录在iStart数组中
            if(a[i][j]==end[i])
                iEnd[i]=j;  //记录终止字符串
        }
    }

    //这个循环完成计算总数,其中调用Count函数,计算结果与实际总数小1,但这个结果正是后面需要的,所以不必再自加1
    for(i=0;i<8;i++)
        total+=Count(iStart[i],iEnd[i],i);

    along=total/n;  //求出每段的长度

    //这个循环进行每段长度的进制转换,结果储存在mod数组里
    for(i=0;i<8;i++)
    {
        mod[i]=along%3;
        along/=3;
    }

    //这个循环计算每个分割点在表中的位置
    for(i=0;i<=n;i++)  //i表示第i个分割点
    {
        for(j=0;j<8;j++)
        {
            if(i==0)  //当分割点为第一个时将初始值赋与每段长度相加
                iMid[0][j]=iStart[j]+mod[j];
            else  //当分割点不是第一个时将上一个分段点与每段的长度相加
                iMid[i][j]=iMid[i-1][j]+mod[j];

            if(Carry==true)  //如果低位有进位那么高位要加1
                iMid[i][j]++;

            if(iMid[i][j]>=3)  //判断是否有进位
            {
                iMid[i][j]-=3;  //如果有进位,要减去进制数
                Carry=true;
            }
            else
                Carry=false;
        }
    }

    //循环完成打印所有的分段点
    for(i=0;i    {
        for(j=0;j<8;j++)
        {
            k=iMid[i][j];  //k所记录的正是每个字符所在表中的位置
            cout<        }
        cout<    }

    //由于不知道是否是均分,所以最后一个分段点可能与终止值不同,用这个循环来判断一下
    for(i=0;i<8;i++)
    {
        k=iMid[n-1][i];
        if(a[i][k]!=end[i])
        {
            TheEnd=false;
            break;
        }
    }

    //如果不同,再把终止值显示出来,以保证程序的完整性
    if(!TheEnd)
    {
        for(i=0;i<8;i++)
            cout<        cout<    }

    system("Pause");
    return 0;
}

//计算总数需要用到的函数
int Count(int x,int y,int k)
{
    int i;
    int z=y-x;
    for(i=0;i        z*=3;
    return z;
}

--------------------next---------------------
/*
程序经过了修改,输出结果只保留分段点,如分成4分,则显示3个分段点。
起始字符串和终止字符串由键盘输入,分成的份数也由键盘输入。
输入数据时为符合习惯修改为从高位到低位依次输入。
对进制数进行了宏定义,方便修改。

仅没有考虑类似8位98进制时total和along数据超出int范围的情况。
*/
#include
#define M 3

int Count(int,int,int);

int main(void)
{

/*
    bool TheEnd=true; //因为不知道是否能够平均分配,用TheEnd来判断,TheEnd为false时无法平均分。
*/

    bool Carry=false;  //用来进行进位的标识,当Carry为true时需进位。
    int i,j,k;
    int total=0;  //记录总长度
    int n,along;  //记录分段数和每段的长度
    int iStart[8],iEnd[8],iMid[10][8];  //前两个变量记录起始字符串和终止字符串在表中的位置,最后一个变量记录分段点的位置
    int mod[8];  //进制转换时需要用到的变量

    //  将表输入到这个数组,按照由低位到高位的顺序
    char a[8][M]={
                  {'f','g','8'},
                  {'9','0','4'},
                  {'b','5','h'},
                  {'3','c','a'},
                  {'w','9','7'},
                  {'3','2','y'},
                  {'a','3','b'},
                  {'1','7','9'}
                 };

    char start[8];
    char end[8];

    cout<<"输入起始字符串:";
    for(i=7;i>=0;i--)
        cin>>start[i];

    cout<<"输入终止字符串:" ;
    for(i=7;i>=0;i--)
        cin>>end[i];

    cout<<"分成的份数:";
    cin>>n;

    //这个循环完成记录起始字符串和终止字符串在表中的位置
    for(i=0;i<8;i++)
    {
        for(j=0;j        {
            if(a[i][j]==start[i])
                iStart[i]=j;  //将起始字符串的位置记录在iStart数组中
            if(a[i][j]==end[i])
                iEnd[i]=j;  //记录终止字符串
        }
    }

    //这个循环完成计算总数,其中调用Count函数,计算结果与实际总数小1,但这个结果正是后面需要的,所以不必再自加1
    for(i=0;i<8;i++)
        total+=Count(iStart[i],iEnd[i],i);

    along=total/n;  //求出每段的长度

    //这个循环进行每段长度的进制转换,结果储存在mod数组里
    for(i=0;i<8;i++)
    {
        mod[i]=along%M;
        along/=M;
    }

    //这个循环计算每个分割点在表中的位置
    for(i=0;i<=n;i++)  //i表示第i个分割点
    {
        for(j=0;j<8;j++)
        {
            if(i==0)  //当分割点为第一个时将初始值赋与每段长度相加
                iMid[0][j]=iStart[j]+mod[j];
            else  //当分割点不是第一个时将上一个分段点与每段的长度相加
                iMid[i][j]=iMid[i-1][j]+mod[j];

            if(Carry==true)  //如果低位有进位那么高位要加1
                iMid[i][j]++;

            if(iMid[i][j]>=M)  //判断是否有进位
            {
                iMid[i][j]-=M;  //如果有进位,要减去进制数
                Carry=true;
            }
            else
                Carry=false;
        }
    }

    //循环完成打印所有的分段点
    for(i=0;i    {
        for(j=7;j>=0;j--)
        {
            k=iMid[i][j];  //k所记录的正是每个字符所在表中的位置
            cout<        }
        cout<    }

/************************************************************************************
    //由于不知道是否是均分,所以最后一个分段点可能与终止值不同,用这个循环来判断一下
    for(i=7;i>=0;i--)
    {
        k=iMid[n-1][i];
        if(a[i][k]!=end[i])
        {
            TheEnd=false;
            break;
        }
    }

    //如果不同,再把终止值显示出来,以保证程序的完整性
    if(!TheEnd)
    {
        for(i=7;i>=0;i--)
            cout<        cout<    }
*************************************************************************************/

    system("Pause");
    return 0;
}

//计算总数需要用到的函数
int Count(int x,int y,int k)
{
    int i;
    int z=y-x;
    for(i=0;i        z*=M;
    return z;
}

--------------------next---------------------
 guohao兄:

 我试了8*26的表,即 26个小写字母,将total和along改成了unsigned __int64类型,去掉  了“/************************************************************************************ //由于不知道是否是均分,所以最后一个分段点可能与终止值不同,用这个循环来判断一下”这段的注释符号/*和*/

然后输入八个a和八个z,结果有些出入,就是感觉最后一个分段有问题。于是我在八个a和八个f之间测试了下,发现了同样的问题,就是最后一个分段跳跃的太多,这个问题是怎么出现的?
 
              #define M 26  
  字母表如下定义:char a[8][M]={
                                  {'a','b','c','d','e','f','g','h','i','j','k','l','m',                    
                                   'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                {'a','b','c','d','e','f','g','h','i','j','k','l','m',                  
                                    'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                                   {'a','b','c','d','e','f','g','h','i','j','k','l','m',                    
                                    'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
             {'a','b','c','d','e','f','g','h','i','j','k','l','m',                  
                                    'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
  {'a','b','c','d','e','f','g','h','i','j','k','l','m',                  
                                   'n','o','p','q','r','s','t','u','v','w','x','y','z'},                
                   
             {'a','b','c','d','e','f','g','h','i','j','k','l','m',                    
                                    'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                                  {'a','b','c','d','e','f','g','h','i','j','k','l','m',                    
                                   'n','o','p','q','r','s','t','u','v','w','x','y','z'},              
                   
             {'a','b','c','d','e','f','g','h','i','j','k','l','m',                  
                                    'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                  };


--------------------next---------------------
/*
输出结果为各分段点,如分成4分,则显示3个分段点。
起始字符串和终止字符串由键盘输入,分成的份数也由键盘输入。
输入数据从高位到低位依次输入。
对进制数和分段数进行了宏定义,使用时要注意。
可以处理类似8×98的表。
*/
#include
#define M 26  //定义进制数
#define N 29  //对分段数量的限制

unsigned __int64 Count(int,int,int);

int main(void)
{
    bool Carry=false;  //用来进行进位的标识,当Carry为true时需进位。
    int i,j,k;
    unsigned __int64 total=0;  //记录总长度
    unsigned __int64 along;    //记录每段长度
    int n;  //记录分段数
    int iStart[8],iEnd[8];  //分别记录起始字符串和终止字符串在表中的位置
    int iMid[N][8];  //记录分段点的位置。waring!注意宏定义,分段数量不能超过定义数组的大小,如int iMid[29][8];则最多分30段
    int mod[8];  //进制转换时需要用到的变量

    //  将表输入到这个数组,按照由低位到高位的顺序
    char a[8][M]={
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                   
                 {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                  'n','o','p','q','r','s','t','u','v','w','x','y','z'},
                 };

    char start[8];
    char end[8];

    cout<<"输入起始字符串:";
    for(i=7;i>=0;i--)
        cin>>start[i];

    cout<<"输入终止字符串:" ;
    for(i=7;i>=0;i--)
        cin>>end[i];

    cout<<"分成的份数(1~"<    cin>>n;

    //这个循环完成记录起始字符串和终止字符串在表中的位置
    for(i=0;i<8;i++)
    {
        for(j=0;j        {
            if(a[i][j]==start[i])
                iStart[i]=j;  //将起始字符串的位置记录在iStart数组中
            if(a[i][j]==end[i])
                iEnd[i]=j;  //记录终止字符串
        }
    }

    //这个循环完成计算总数,其中调用Count函数,计算结果与实际总数小1,但这个结果正是后面需要的,所以不必再自加1
    for(i=0;i<8;i++)
        total+=Count(iStart[i],iEnd[i],i);

    along=total/(unsigned __int64)n;  //求出每段的长度

    //这个循环进行每段长度的进制转换,结果储存在mod数组里
    for(i=0;i<8;i++)
    {
        mod[i]=(int)(along%(unsigned __int64)M);
        along/=(unsigned __int64)M;
    }

    //这个循环计算每个分割点在表中的位置
    for(i=0;i    {
        for(j=0;j<8;j++)
        {
            if(i==0)  //当分割点为第一个时将初始值赋与每段长度相加
                iMid[0][j]=iStart[j]+mod[j];
            else  //当分割点不是第一个时将上一个分段点与每段的长度相加
                iMid[i][j]=iMid[i-1][j]+mod[j];

            if(Carry==true)  //如果低位有进位那么高位要加1
                iMid[i][j]++;

            if(iMid[i][j]>=M)  //判断是否有进位
            {
                iMid[i][j]-=M;  //如果有进位,要减去进制数
                Carry=true;
            }
            else
                Carry=false;
        }
    }

    //循环完成打印所有的分段点
    for(i=0;i    {
        cout<<"分段点"<        for(j=7;j>=0;j--)
        {
            k=iMid[i][j];  //k所记录的正是每个字符所在表中的位置
            cout<        }
        cout<    }

    system("Pause");
    return 0;
}

//计算总数需要用到的函数
unsigned __int64 Count(int x,int y,int k)
{
    int i;
    unsigned __int64 z=(unsigned __int64)y-(unsigned __int64)x;
    for(i=0;i        z*=(unsigned __int64)M;
    return z;
}

--------------------next---------------------
#include
#include
#define M 26  //定义进制数
#define N 29  //对分段数量的限制

unsigned __int64 Count(int,int,int);

int main(void)
{
    bool Carry=false;  //用来进行进位的标识,当Carry为true时需进位。
    int i,j,k;
    unsigned __int64 total=0;  //记录总长度
    unsigned __int64 along;    //记录每段长度
    int n;  //记录分段数
    int iStart[8],iEnd[8];  //分别记录起始字符串和终止字符串在表中的位置
    int iMid[N][8];  //记录分段点的位置。waring!注意宏定义,分段数量不能超过定义数组的大小,如int iMid[29][8];则最多分30段
    int mod[8];  //进制转换时需要用到的变量

    //  将表输入到这个数组,按照由低位到高位的顺序
    char a[8][M]={……};

    char start[8];
    char end[8];

    cout<<"输入起始字符串:";
    for(i=7;i>=0;i--)
        cin>>start[i];

    cout<<"输入终止字符串:" ;
    for(i=7;i>=0;i--)
        cin>>end[i];

    cout<<"分成的份数(1~"<    cin>>n;

    //这个循环完成记录起始字符串和终止字符串在表中的位置
    for(i=0;i<8;i++)
    {
        for(j=0;j        {
            if(a[i][j]==start[i])
                iStart[i]=j;  //将起始字符串的位置记录在iStart数组中
            if(a[i][j]==end[i])
                iEnd[i]=j;  //记录终止字符串
        }
    }

    //这个循环完成计算总数,其中调用Count函数,计算结果与实际总数小1,但这个结果正是后面需要的,所以不必再自加1
    for(i=0;i<8;i++)
        total+=Count(iStart[i],iEnd[i],i);

    along=total/(unsigned __int64)n;  //求出每段的长度

    //这个循环进行每段长度的进制转换,结果储存在mod数组里
    for(i=0;i<8;i++)
    {
        mod[i]=(int)(along%(unsigned __int64)M);
        along/=(unsigned __int64)M;
    }

    //这个循环计算每个分割点在表中的位置
    for(i=0;i    {
        for(j=0;j<8;j++)
        {
            if(i==0)  //当分割点为第一个时将初始值赋与每段长度相加
                iMid[0][j]=iStart[j]+mod[j];
            else  //当分割点不是第一个时将上一个分段点与每段的长度相加
                iMid[i][j]=iMid[i-1][j]+mod[j];

            if(Carry==true)  //如果低位有进位那么高位要加1
                iMid[i][j]++;

            if(iMid[i][j]>=M)  //判断是否有进位
            {
                iMid[i][j]-=M;  //如果有进位,要减去进制数
                Carry=true;
            }
            else
                Carry=false;
        }
    }

    //修改的地方从这里开始******************************************************************

    cout<<"第1段:";
    for(i=7;i>=0;i--)
        printf("%3d",iStart[i]);
    cout<<" ---";

    for(i=0;i    {

        for(j=7;j>=0;j--)
        {
            k=iMid[i][j];  //k所记录的正是每个字符所在表中的位置
            printf("%3d",k);
            //cout<        }
        cout<
        cout<<"第"<
        for(j=7;j>=0;j--)
        {
            k=iMid[i][j];  //k所记录的正是每个字符所在表中的位置
            printf("%3d",k);
            //cout<        }
        cout<<" ---";
    }
    for(i=7;i>=0;i--)
        printf("%3d",iEnd[i]);
    cout<
    system("Pause");
    return 0;
}

--------------------next---------------------

 自己修改了下,运行没问题,就是不知道结果对不对~
你帮我检查检查!


#include "stdafx.h"
#include
#include
#include


//unsigned __int64 Count(int,int,int);

int main(void)
{
   bool Carry=false;  //用来进行进位的标识,当Carry为true时需进位。
    int i,j,k;
    unsigned __int64 total=1;  //记录总长度
    unsigned __int64 along;    //记录每段长度
    int n;  //记录分段数  
    int iMid[100][8];  //记录分段点的位置
    int mod[8];  //进制转换时需要用到的变量
    char passstart[8]={0,0,0,0,0,0,0,0};//分别记录起始字符串和终止字符串
    char passstop[8]={51,51,51,51,51,51,51,51};
    cout<<"分成的份数(1~100):";
    cin>>n;  
    for(i=0;i<8;i++)
        total=total*52;

      along=total/(unsigned __int64)n;  //每段的长度

    //这个循环进行每段长度的进制转换,结果储存在mod数组里
    for(i=0;i<8;i++)
    {
        mod[i]=(int)(along%52);
        along/=52;
    }

    //这个循环计算每个分割点在表中的位置
    for(i=0;i    {
        for(j=0;j<8;j++)
        {
            if(i==0)  //当分割点为第一个时将初始值赋与每段长度相加
                iMid[0][j]=passstart[j]+mod[j];
            else  //当分割点不是第一个时将上一个分段点与每段的长度相加
                iMid[i][j]=iMid[i-1][j]+mod[j];

            if(Carry==true)  //如果低位有进位那么高位要加1
                iMid[i][j]++;

            if(iMid[i][j]>=52)  //判断是否有进位
            {
                iMid[i][j]-=52;  //如果有进位,要减去进制数
                Carry=true;
            }
            else
                Carry=false;
        }
    }


cout<<"第1段:";
    for(i=7;i>=0;i--)
        printf("%3d",passstart[i]);
   

    for(i=0;i {

        for(j=7;j>=0;j--)
        {
            k=iMid[i][j];  //k所记录的正是每个字符所在表中的位置
            printf("%3d",k);
           
        }
        cout<
        cout<<"第"<
        for(j=7;j>=0;j--)
        {
            k=iMid[i][j];  //k所记录的正是每个字符所在表中的位置
            printf("%3d",k);
           
        }
       
    }
    for(i=7;i>=0;i--)
        printf("%3d",passstop[i]);
    cout<
    return 0;
}

--------------------next---------------------

阅读(1264) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~