求解一道题目有关循环及数组问题
本帖最后由 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表示个位的7
a表示十位的4
a表示百位的6
.....以此类推
#include <stdio.h>
main(void)
{
int a , n , Sn , b , i , k , m ;
for(m = 0 ;;) {
scanf("%d%d" , & n , & a) ;
if(n) m ++ ;
else break ;
}
for(k = 0 ; k < m ; k ++) {
for(Sn = 0 , b = a , i = 0 ; i < n ; i ++ , b = b * 10 + a) Sn += b ;
printf("%d\n" , Sn) ;
}
}
编译、运行实况:
D:\00.Excise\C>g++ -o x x.c
D:\00.Excise\C>x
2 4
3 8
4 9
5 2
8 7
10 1
0 0
48
984
11106
24690
86419746
1234567900
D:\00.Excise\C> 本帖最后由 ckh020303 于 2020-11-8 16:11 编辑
jackz007 发表于 2020-11-8 12:48
编译、运行实况:
你好,你这个代码和我的是一个情况的,我去试了下,当n=1000时,sn只能取到差不多2147483647,而答案的sn是1000位数的,我想要了解的是可不可以把一个很大位数的数,每一位数用一个数组来表示,举例如下:
就如2147483647 a表示个位的7
a表示十位的4
a表示百位的6
.....以此类推
最后逆向输出来
ckh020303 发表于 2020-11-8 16:09
你好,你这个代码和我的是一个情况的,我去试了下,当n=1000时,sn只能取到差不多2147483647,而答案的 ...
1000 位数的整型数你准备用什么数据类型来保存,用什么手段来做运算?
#include <stdio.h>
int main(void)
{
long long a , d , k , m , n ;
n = 2147483647 ;
for(d = n, m = 0 ; d ; d /= 10 , m ++) a = d % 10 ;
printf("%I64d" , a) ;
for(k = m - 1 ; k ; k --) printf(" %I64d" , a);
printf("\n") ;
}
编译、运行实况:
D:\00.Excise\C>g++ -o x x.c
D:\00.Excise\C>x
2 1 4 7 4 8 3 6 4 7
D:\00.Excise\C>
大整数的加减乘除都有。
#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 = 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<'0' || number>'9')
{
break;
}
}
if(i < nLen--)
{
break;
}
for(i=nLen ; i>=0 ; i--)
{
if((nLen - i) % NUM_LEN == 0)
{
if(nLen - i != 0)
{
pNum->_num = value;
}
value = 0;
power = 1;
}
cByte = number - 0x30;
value += power * cByte;
power *= 10;
}
if(value != 0)
{
pNum->_num = 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 = {0};
do
{
if(!IS_INITED(pNum))
{
break;
}
if(number == 0)
{
nRet = pNum->_len * NUM_LEN + 1;
break;
}
number = 0;
for(i=pNum->_len-1 ; i>=0 ; i--)
{
if(i == pNum->_len-1)
{
sprintf(buffer,"%d",pNum->_num);
}
else
{
sprintf(buffer,"%09d",pNum->_num);
}
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 + number + carry;
pNum->_num = value % BASE;
carry = value / BASE;
}
if(carry != 0)
{
pNum->_num = 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;
}
if(i < pAdd->_len)
{
value += pAdd->_num;
}
pNum->_num = value % BASE;
carry = value / BASE;
}
if(carry != 0)
{
pNum->_num = 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,
MUL number
ADD EAX,carry
ADC EDX,0
MOV EBX,BASE
DIV EBX
MOV ,EDX
MOV carry,EAX
ADD ESI,4
}
}
if(carry != 0)
{
pNum->_num = 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,
ADC EDX,0
MOV EBX,number
DIV EBX
MOV ,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 = {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;
} 运行结果
xieglt 发表于 2020-11-9 10:10
运行结果
兄弟太猛了
页:
[1]