读书人

大数运算有关问题

发布时间: 2012-08-16 12:02:15 作者: rapoo

大数运算问题
最近做了北大POJ1312遇到了一个问题。题目要求把输入的数或者字符串按照26进制转换。比如a=1,z=26,aa=27,az=52.以此类推。题目给的测试数据是29697684282993
transcendental
28011622636823854456520
computationally
zzzzzzzzzzzzzzzzzzzz
我不懂得就是题目的数已经超过整型范围了,我该用什么来存储这么大的数?如何操作?求教高人给出思路(题目中的26进制互相转换我会,但不会处理过大的数。)我自己的程序一遇到大数据就崩了。

[解决办法]
这个需要自己写一个处理大数的数据结构,重载4则运算即可。如果你不会可以搜一下BigInteger Class
[解决办法]
把数存成string型 自己重载四则运算 基本概念就是这样的 不过26进制貌似比较复杂啊
[解决办法]
就用字符串模拟就行
[解决办法]
用数组模拟大数,一个长度为1000的数组可以模拟一个1000位的数字。
[解决办法]
lz有点想偏了,这个问题其实不需要大数运算。
http://blog.csdn.net/g_idea/article/details/7673269
[解决办法]
帮你写出来代码了,你可以参考一下~
测试结果:
29697684282993 对应的单词是 elementary
transcendental 对应的数字是 051,346,529,199,396,181,750
028,011,622,636,823,854,456,520 -> prestidigitation
computationally -> 232,049,592,627,851,629,097
zzzzzzzzzzzzzzzzzzzz -> 020,725,274,851,017,785,518,433,805,270

C/C++ code
#include <stdio.h>#include <string.h>#define N 128typedef unsigned short u_16;//输入函数void input( u_16 *l, const char *s ){   //将数字字符串替换成 u_16数组,方便函数计算    memset( l, 0, N*sizeof(u_16) );    char ts[N] = {0};    strcpy( ts, s );    int len = strlen( s );    int x = len % 3;    int y = (len-1) / 3 ;    if( x == 0 ) x = 3;    for( int i = y; i > 0; --i )    {   //循环放入u_16数组        ts[i*3+x] = 0;        sscanf( ts+i*3-3+x, "%d", l+y-i );    }    //写字符串的前x个数字(即u_16数组中的最后一个元素)    ts[x] = 0;    sscanf( ts, "%d", l+y );    }//输出函数void output( u_16 *l ){    int i;    for( i = N-1; i >= 0; --i )        if( l[i] ) break;    for( ; i >= 0; --i )    printf( "%03d,", l[i] );    //%03d,  可以去掉这个逗号    printf( "\n" );}//字母转数字void Al2Num( const char *s, u_16 *l ){    int len = strlen( s );    int w = 0;  //进位    for( int i = 0; i < len; ++i )    {        int c = (s[i]&0x5f) - 'A';  //小写字母转大写        for( int j = 0; j < N; ++j )    //大数乘以26并进位        {            l[j] *= 26;            l[j] += w, w = 0;            if( j == 0 ) l[j] += c+1;   // a -> 1, z -> 26            if( l[j] >= 1000 ) w = l[j] / 1000, l[j] %= 1000;        }    }}//数字转字母void Num2Al( const u_16 *l, char *s ){    u_16 tl[N] = {0};    char ts[N] = {0};    memcpy( tl, l, N*sizeof(u_16) );    int i, t = 0, w = 0;    for( i = N-1; i >= 0; --i )     //找到第一个不是0的元素        if( tl[i] ) break;    while( i >= 0 )         //进制转化    {        for( int j = i; j > 0; --j )        {            tl[j-1] += tl[j] % 26 * 1000;            tl[j] /= 26;        }        w = tl[0] % 26;        tl[0] /= 26;        if( w == 0 )        {            if( tl[0] || i ) tl[0] -= 1;            ts[t++] = 'z';        }        else ts[t++] = 'a' + w - 1;        if( tl[i] == 0 ) --i;    }    //字符串倒置赋值    int len = strlen( ts );    for( i = 0; i < len; ++i )        s[len-i-1] = ts[i];    s[len] = 0;}//主函数int main(){    u_16 num[N] = {0};    char al[N] = "zzzzzzzzzzzzzzzzzzzz";    Al2Num( al, num );    //测试输出    printf( "%s\n", al );    output( num );        u_16 num2[N] = {0};//{ 520, 456, 854, 823, 636, 622, 11, 28 };    input( num2, "29697684282993");    char al2[N] = "";    Num2Al( num2, al2 );    output( num2 );    printf( "%s\n", al2 );}
[解决办法]
用64位整数就可以了,没有超出范围。
本人电脑上long long是64位的,long和int都是32位。


[解决办法]
设计一个模板类 将处理字符串按照类型解析 自定义操作运算符 就是重载 也是对字符串进行操作

读书人网 >软件架构设计

热点推荐