|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 ckh020303 于 2020-11-8 16:11 编辑
我写出来的答案是这样的:
#include <stdio.h>
int main()
{
long long int a, n, i = 1, sn = 0,tn = 0;
while(scanf("%lld %lld", &n, &a) != EOF) //多组数据,循环输入并带入n,a;
{
while(i<=n)
{
tn = tn + a;
sn = sn + tn; //当a = 1时,大致为:1 + (10 +1) + (100 +11) + (1000 + 111)……
a = a * 10;
++i;
}
printf("%lf\n", sn);
sn = 0; //归零,不与下次结果冲突
i = 1; //同上
tn = 0;
}
return 0;
}
这个答案在n取值比较小的时候成立,但是n可以取到1000,也就是要输出1000位数;
我想到了用数组来求解,把这个输出的数字,按照个位十位等等用数组来表示输出,但是我不会实践,所以请各位鱼友来帮帮我,教我如何用数组来表示每一位数,最好有注释表明,谢谢!
我想要了解的是可不可以把一个很大位数的数,每一位数用一个数组来表示,举例如下:就如2147483647
a[0]表示个位的7
a[1]表示十位的4
a[2]表示百位的6
.....以此类推
大整数的加减乘除都有。
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- /***********************************************************************************
- 用整形数组解决大数高精度计算问题
- 32位系统下 unsigned int 最大存储的数为:4294967296
- 为了防止最高位为1导致负数的问题,数组中每个元素最大只存储 999999999
- 为了解决溢出问题,在做乘法和除法的时候用到了内嵌汇编,某些编译器可能不支持
- ***********************************************************************************/
- #define BASE (1000000000)
- #define NUM_LEN (9)
- #define IS_INITED(p) ((p->_num != 0) && (p->_initFlag == 0))
- //定义一个结构体来存储大整数
- typedef struct tagNumeric
- {
- //存储大数的数组
- int * _num;
- //为数组分配的内存大小,以 int 为单位,计算字节数则为:_size * sizeof(int)
- int _size;
- //大数的长度,即数组中的有用长度
- int _len;
- //结构体初始化标记
- //鉴于某些编译器初始化变量,某些编译器不初始化变量
- //因此,认为 _initFlag == 0 && _num != 0 时,结构体被初始化
- int _initFlag;
- }NUMERIC,*LPNUMERIC;
- //初始化大整数结构体,为数组分配内存
- int InitNumeric(LPNUMERIC pNum,int size)
- {
- int nRet = 0;
- do
- {
- if(IS_INITED(pNum))
- {
- break;
- }
- pNum->_num = (int *)malloc(size * sizeof(int));
- if(pNum->_num == 0)
- {
- break;
- }
- memset(pNum->_num,0,size*sizeof(int));
- pNum->_len = 0;
- pNum->_initFlag = 0;
- pNum->_size = size;
- nRet = 1;
- }while(0);
- return nRet;
- }
- //当分配的内存不足以存储大整数时,为之重新分配内存
- //建议为防止内存频繁地被重新分配,可以在初始化时分配大一点
- int ReinitNumeric(LPNUMERIC pNum,int size)
- {
- int nRet = 0;
-
- do
- {
- if(!IS_INITED(pNum))
- {
- break;
- }
-
- if(size <= pNum->_size)
- {
- break;
- }
-
- pNum->_num = (int *)realloc(pNum->_num,size*sizeof(int));
- if(pNum->_num == 0)
- {
- break;
- }
- memset(pNum->_num + pNum->_size,0,(size - pNum->_size)*sizeof(int));
- pNum->_size = size;
- nRet = 1;
- }while(0);
-
- return nRet;
- }
- //释放内存
- void UninitNumeric(LPNUMERIC pNum)
- {
- if(IS_INITED(pNum))
- {
- free(pNum->_num);
- pNum->_num = 0;
- }
- }
- //给结构体一个初始整数值,这个值必须小于 1000000000
- int SetNumber(LPNUMERIC pNum,int number)
- {
- int nRet = 0;
-
- do
- {
- if(number >= BASE)
- {
- break;
- }
- if(!IS_INITED(pNum) && InitNumeric(pNum,1)==0)
- {
- break;
- }
-
- pNum->_num[0] = number;
- pNum->_len = 1;
- nRet = 1;
- }while(0);
- return nRet;
- }
- //当需要给结构体一个大于999999999的初始值时,
- //可以用字符串形式给它赋值,实例如下:
- /*
- NUMERIC num;
- SetNumeric(&num,"1234567890987654321");
- */
- int SetNumeric(LPNUMERIC pNum,char * number)
- {
- int i = 0;
- int nRet = 0;
- char cByte = 0;
- int value = 0;
- int power = 0;
- int index =0;
- int nLen = strlen(number);
- int size = nLen / NUM_LEN + (nLen % NUM_LEN == 0 ? 0 : 1);
-
-
- do
- {
- if(nLen == 0)
- {
- break;
- }
-
- if(!IS_INITED(pNum) && InitNumeric(pNum,size) == 0)
- {
- break;
- }
- if(size > pNum->_size && ReinitNumeric(pNum,size) == 0)
- {
- break;
- }
-
- for(i=0 ; i<nLen ; i++)
- {
- if(number[i]<'0' || number[i]>'9')
- {
- break;
- }
- }
- if(i < nLen--)
- {
- break;
- }
- for(i=nLen ; i>=0 ; i--)
- {
- if((nLen - i) % NUM_LEN == 0)
- {
- if(nLen - i != 0)
- {
- pNum->_num[index++] = value;
- }
- value = 0;
- power = 1;
- }
- cByte = number[i] - 0x30;
- value += power * cByte;
- power *= 10;
- }
- if(value != 0)
- {
- pNum->_num[index++] = value;
- }
- pNum->_len = index;
- nRet = 1;
- }while(0);
- return nRet;
- }
- //将大整数转化成字符串,以便于输出。
- //当 number 指针传 0 时,函数将返回转化成字符串所需要的内存空间
- //实例如下:
- /*
- int len =0;
- char * buffer;
- NUMERIC num;
- SetNumeric(&num,"12345678909876543121");
- len = Number2String(&num,0);
- buffer = (char *)malloc(len);
- Number2String(&num,buffer);
- */
- int Number2String(LPNUMERIC pNum,char * number)
- {
- int i = 0;
- int nRet = 0;
- char buffer[16] = {0};
-
- do
- {
- if(!IS_INITED(pNum))
- {
- break;
- }
- if(number == 0)
- {
- nRet = pNum->_len * NUM_LEN + 1;
- break;
- }
- number[0] = 0;
-
- for(i=pNum->_len-1 ; i>=0 ; i--)
- {
- if(i == pNum->_len-1)
- {
- sprintf(buffer,"%d",pNum->_num[i]);
- }
- else
- {
- sprintf(buffer,"%09d",pNum->_num[i]);
- }
- strcat(number,buffer);
- }
- nRet = strlen(number);
- }while(0);
- return nRet;
- }
- //大整数与一个 int 相加
- int AddNumber(LPNUMERIC pNum,int number)
- {
- int i;
- int nRet = 0;
- int carry = 0;
- unsigned int value = 0;
-
- do
- {
- if(!IS_INITED(pNum))
- {
- break;
- }
-
- if(pNum->_size == pNum->_len && ReinitNumeric(pNum,pNum->_size + 1) == 0)
- {
- break;
- }
-
- for(i=0 ; i<pNum->_len ; i++)
- {
- value = pNum->_num[i] + number + carry;
- pNum->_num[i] = value % BASE;
- carry = value / BASE;
- }
-
- if(carry != 0)
- {
- pNum->_num[i++] = carry;
- }
- pNum->_len = i;
-
- nRet = 1;
- }while(0);
-
- return nRet;
- }
- //大整数加另外一个大整数
- int AddNumeric(LPNUMERIC pNum,LPNUMERIC pAdd)
- {
- int i;
- int nRet = 0;
- int carry = 0;
- int size = 0;
- unsigned int value = 0;
-
- do
- {
- if(!IS_INITED(pNum) || !IS_INITED(pAdd))
- {
- break;
- }
-
- if(pNum->_size < pAdd->_len)
- {
- size = pAdd->_len + 1;
- }
- else if(pNum->_size == pNum->_len)
- {
- size = pNum->_size + 1;
- }
- if(size != 0 && ReinitNumeric(pNum,size) == 0)
- {
- break;
- }
-
- size = pNum->_len > pAdd->_len ? pNum->_len : pAdd->_len;
- for(i=0 ; i<size ; i++)
- {
- value = carry;
- if(i < pNum->_len)
- {
- value += pNum->_num[i];
- }
- if(i < pAdd->_len)
- {
- value += pAdd->_num[i];
- }
- pNum->_num[i] = value % BASE;
- carry = value / BASE;
- }
-
- if(carry != 0)
- {
- pNum->_num[i++] = carry;
- }
- pNum->_len = i;
-
- nRet = 1;
- }while(0);
-
- return nRet;
- }
- //大整数与一个 int 相乘
- int MulNumber(LPNUMERIC pNum,int number)
- {
- int i;
- int nRet = 0;
- int carry = 0;
- int * plong = 0;
- do
- {
- if(!IS_INITED(pNum))
- {
- break;
- }
- if(pNum->_size == pNum->_len && ReinitNumeric(pNum,pNum->_size + 1) == 0)
- {
- break;
- }
- plong = pNum->_num;
- _asm
- {
- MOV ESI,plong
- }
-
- for(i=0 ; i<pNum->_len ; i++)
- {
- _asm
- {
- MOV EAX,[ESI]
- MUL number
- ADD EAX,carry
- ADC EDX,0
- MOV EBX,BASE
- DIV EBX
- MOV [ESI],EDX
- MOV carry,EAX
- ADD ESI,4
- }
- }
- if(carry != 0)
- {
- pNum->_num[i++] = carry;
- }
- pNum->_len = i;
- nRet = 1;
- }while(0);
- return nRet;
- }
- //大整数与一个 int 相除
- int DivNumber(LPNUMERIC pNum,int number)
- {
- int nRet = 0;
- int carry = pNum->_len;
- int * plong = pNum->_num;
- do
- {
- if(!IS_INITED(pNum))
- {
- break;
- }
-
- plong += (pNum->_len - 1);
- _asm
- {
- MOV ECX,carry
- MOV ESI,plong
- XOR EDX,EDX
- _DivLoop:
- MOV EAX,EDX
- MOV EBX,BASE
- MUL EBX
- ADD EAX,[ESI]
- ADC EDX,0
- MOV EBX,number
- DIV EBX
- MOV [ESI],EAX
- SUB ESI,4
- TEST EAX,EAX
- JNZ _NotZero
- DEC carry
- _NotZero:
- LOOP _DivLoop
- }
- pNum->_len = carry;
- nRet = 1;
- }while(0);
- return nRet;
- }
- int main()
- {
- int i;
- int n,a;
- NUMERIC sum,num;
- char buffer[4096] = {0};
- InitNumeric(&sum,100);
- InitNumeric(&num,100);
- while(1)
- {
- scanf("%d%d",&n,&a);
- if(n == 0)
- {
- break;
- }
- sprintf(buffer,"%d",a);
- SetNumeric(&sum,buffer);
- for(i=1 ; i<n ; i++)
- {
- sprintf(buffer,"%s%d",buffer,a);
- SetNumeric(&num,buffer);
- AddNumeric(&sum,&num);
- }
- Number2String(&sum,buffer);
- printf("%s\n",buffer);
- }
- UninitNumeric(&num);
- UninitNumeric(&sum);
- return 0;
- }
复制代码
|
|