大数运算问题
最近做了北大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位。
[解决办法]
设计一个模板类 将处理字符串按照类型解析 自定义操作运算符 就是重载 也是对字符串进行操作