前言
今天分享一题有关竖式乘法的OJ
题目
我的想法
我将竖式乘法分为两个部分,
和
从图中我们可以发现,无论两个数字有几位数,式子的列宽均为相乘结果的位数+1,故可以在一开始求出结果来确定列宽
确定列宽
//di函数,计算数据位数
int di(int a) {
int t = 0;
while (a != 0) {
a /= 10;
t++;
}
return t;
}
//pow函数,进行乘方运算
int pow(int m, int n)
{
int k = m;
if (m != 0)
{
if (n == 0)
m = 1;
if (n >= 1)
m = 1;
while (n != 0)
{
m *= k;
n--;
}
}
return m;
}
//取大函数
int MAX(int m, int n) {
if (m > n)
return m;
else
return n;
}
//取小函数
int MIN(int m, int n) {
if (m < n)
return m;
else
return n;
}
//绝对值函数
int fabs(int x) {
if (x < 0)
x = -x;
return x;
}
//取数字第一位函数
int first(int x) {
int n = di(x);
int m = pow(10, n - 1);
return x / m;
}
int main() {
int a = 0, b = 0;
//输入乘数
scanf("%d%d", &a, &b);
//先求结果
long long n = a * b;
//则每行总长为di(n)+1
int L = di(n)+1;
// t1为大值,t2为小值,n1 n2分别表示t1 t2的位数
int t1 = MAX(a, b), t2 = MIN(a, b), n1 = di(t1), n2 = di(t2);
//默认把较小数t2放在第二排
第一部分
int t = L;
//第一行,空格数=总列宽-较大数位数
while (t - di(t1) != 0) {
printf(" ");
t--;
}
printf("%d\n", t1);
//第二行,先打印乘号,空格数=总列宽-较大数位数
t = L;
printf("×");
while (t - di(t2) - 1 != 0) {
printf(" ");
t--;
}
printf("%d\n", t2);
//线,总长=总列宽
t = L;
while (t != 1) {
printf("-");
t--;
}
printf("-\n");
所得效果:
第二部分
//第二组第n行
int x = 1;
while (t2 != 0) {
int m = 0, c = 0;
m = t2 % 10;//通过求余算法来获取t2的末尾数字
c = t1 * m;//c即为第x行应打印的数
t = L;
while (t - di(c) - x >= 0) {
//x每+1,c打印时需左移一位
printf(" ");
t--;
}
printf("%d\n", c);
t2 = t2 / 10;//为下一次循环准备
x++;
}
此时所得的结果如下图
因为第二部分还需要一个加号,因此我对其做出修改
int x = 1;
while (t2/10 != 0) {//改为t2/10,将最后一行排除
int m = 0, c = 0;
m = t2 % 10;//通过求余算法来获取t2的末尾数字
c = t1 * m;//c即为第x行应打印的数
t = L;
while (t - di(c) - x >= 0) {
//x每+1,c打印时需左移一位
printf(" ");
t--;
}
printf("%d\n", c);
t2 = t2 / 10;//为下一次循环准备
x++;
}
//打印第二部分最后一行
int m = t2 ;
printf("+%d\n", m * t1);
这样就离结果越来越近了
最后部分
最轻松的时刻
//线
t = l;
while (t != 1) {
printf("-");
t--;
}
printf("-\n");
//结果
printf(" %lld", n);
return 0;
}
整个结果如下
存在的问题
如果t2中有一位数是0,那由于计算结果c=0,会出现以上情况,与题意不符。
因此对于第二部分我们还需完善
1.在内嵌while语句中插入
if (c == 0)
break;
使c=0时不打印空格
——————————————————————————————
2.在外面的while语句中插入
if (c == 0)
continue;
使c=0时不打印数字且不换行
——————————————————————————————
3.注意调换
x++;
t2 = t2 / 10;//为下一次循环准备
if (c == 0)
continue;
printf("%d\n", c);
语句顺序,防止c==0时x不++,t2不/10
int x = 1;
while (t2/10 != 0) {
int m = 0, c = 0;
m = t2 % 10;//通过求余算法来获取t2的末尾数字
c = t1 * m;//c即为第x行应打印的数
t = l;
while (t - di(c) - x >= 0) {
if (c == 0)
break;
//x每+1,c打印时需左移一位
printf(" ");
t--;
}
x++;
t2 = t2 / 10;//为下一次循环准备
if (c == 0)
continue;
printf("%d\n", c);
}
int m = t2 ;
printf("+%d\n", m * t1);
最终效果
总结
理清思路就并不复杂