自从腾讯HR面试被刷后,也就不想找实习了,记住教训吧,没事还有九月份,现在和其他人几个人都加进去了linux3+1实验室,暑假好好干一个暑假。
大数相加虽然之前写过,但是现在写代码起码也应该有自己的风格和规范了,其实大数相加和大数相乘的思路很简单,int我们现在一般用的都是4个字节,最大也是2147483647,简单说21亿,但是更大的数字就从不下了,因为我们可以用数组来模拟大数相乘和大数相加。我们将每一位数字存在数组中,对于每一次处理,通过/10(除10)看进位是几,通过%10(取余)看该位保留几,也就是数组的每一次最后都是小于10的,
大数相乘的代码
#include <stdio.h>
#include <string.h>
#define MAXLEN 500
int flag = 0; //标志数组应该从哪里开始计算
int a[MAXLEN];
int b[MAXLEN];
int c[2*MAXLEN]; //将每一位的计算结果都保存在里面
// 翻转过来好处理
void reverse_str(char *str,int *array,int len)
{
int i = 0;
for(i = 0; i < len; i++){
array[len - i - 1] = str[i] - '0'; //刚开始忘记'0'
}//end for
}
void multiply(int *a,int *b,int *c,int sa_len,int sb_len)
{
int i = 0;
int j = 0;
int sum_len = sa_len + sb_len - 1;
for(i = 0; i < sa_len; i++){
for(j = 0; j < sb_len; j++){
c[i + j] += a[i] * b[j];
printf("c[%d]= %d ",i+j,c[i+j]);
}//end for 2
printf("\n");
}//end for 1
for(i = 0; i < sum_len - 1; i++){
c[i+1] += c[i] / 10;
c[i] %= 10;
}//end for
if(c[i] != 0){
flag = i;
}else{
flag = i - 1;
}//end if else
}
void print_c_array(int *c,int sa_len,int sb_len)
{
int i = 0;
int sum_len = sa_len + sb_len;
for(i = flag; i >= 0; i--){
printf("%d",c[i]);
}//end for
printf("\n");
}
int main(int argc,char *argv[])
{
char sa[MAXLEN];
char sb[MAXLEN];
int sa_len = 0;
int sb_len = 0;
memset(sa,0x00,sizeof(sa));
memset(sb,0x00,sizeof(sb));
gets(sa);
gets(sb);
sa_len = strlen(sa);
sb_len = strlen(sb);
printf("%s %d\n",sa,sa_len);
printf("%s %d\n",sb,sb_len);
reverse_str(sa,a,sa_len);
reverse_str(sb,b,sb_len);
multiply(a,b,c,sa_len,sb_len);
print_c_array(c,sa_len,sb_len);
return 0;
}
大数相加的代码也类似
#include <stdio.h>
#include <string.h>
#define MAXLEN 100
int flag; //标志数组应该从哪里开始计算
int a[MAXLEN];
int b[MAXLEN];
int c[MAXLEN+1]; //将每一位的计算结果都保存在里面
// 翻转过来好处理
void reverse_str(char *str,int *array,int len)
{
int i = 0;
int j = MAXLEN - 1;
// 1 2 3 4 5 6
// 4 5 6
for(i = len - 1; i >= 0; i--){
array[j--] = str[i] - '0';
}//end for
}
void large_number_add(int *a,int *b,int *c,int sa_len,int sb_len)
{
int i = 0;
int j = MAXLEN - 1;
int m = sa_len>sb_len?sa_len:sb_len;
for(i = 0; i < m; i++,j--){
c[j] += a[j] + b[j];
if(c[j] >= 10){
c[j-1] += c[j] / 10;
c[j] = c[j] % 10;
}
printf("c[%d]=%d,c[%d]=%d\n",j,c[j],j-1,c[j-1]);
}
if(c[j] != 0){
flag = j;
}else{
flag = j + 1;
}
}
void print_c_array(int *c,int sa_len,int sb_len)
{
int i = 0;
int sum_len = sa_len + sb_len;
for(i = flag; i < MAXLEN; i++){
printf("%d",c[i]);
}//end for
printf("\n");
}
int main(int argc,char *argv[])
{
char sa[MAXLEN];
char sb[MAXLEN];
int sa_len = 0;
int sb_len = 0;
memset(sa,0x00,sizeof(sa));
memset(sb,0x00,sizeof(sb));
gets(sa);
gets(sb);
sa_len = strlen(sa);
sb_len = strlen(sb);
printf("%s %d\n",sa,sa_len);
printf("%s %d\n",sb,sb_len);
reverse_str(sa,a,sa_len);
reverse_str(sb,b,sb_len);
large_number_add(a,b,c,sa_len,sb_len);
print_c_array(c,sa_len,sb_len);
return 0;
}
100的阶乘也就是这思路,大数都是这样处理的,既然直接存取不了,窝一位一位处理
#include <stdio.h>
#include <string.h>
#define MAXLEN 500
int a[MAXLEN];
void factorial(int *a,int n,int *start)
{
int i = 0;
int j = 0;
int temp = 0;
int carry_bit = 0;
int k = MAXLEN - 2;
int factorial_num = 2;
a[MAXLEN - 1] = 1;
for(i = 1; i < n; i++){
for(j = MAXLEN - 1; j > k;j--){
temp = a[j] * factorial_num + carry_bit;
a[j] = temp % 10;
carry_bit = temp /10;
}//end for
while(carry_bit){
a[k--] += carry_bit % 10;
carry_bit /= 10;
}//end for
factorial_num++;
}//end for
*start = k;
}
void print_array(int *a,int start)
{
int i = 0;
for(i = start + 1; i < MAXLEN; i++){
printf("%d",a[i]);
}//end for
printf("\n");
}
int main(int argc,char *argv[])
{
int n = 0;
int start = 0;
scanf("%d",&n);
factorial(a,n,&start);
print_array(a,start);
return 0;
}
下面这个是一个数的阶乘有多少个0
#include <stdio.h>
#include <math.h>
int main(int argc,char *argv[])
{
int i = 0;
int n = 0;
int k = 5;
int count = 0;
while(scanf("%d",&n) != EOF){
for(i = 1; i <= n; i++){
for(k = 5; k <=pow(5,10); k *= 5){
if(i % k == 0){
count++;
}
}
}
printf("%d\n",count);
count = 0;
}
return 0;
}