上一篇最后留了一個(gè)打印楊輝三角的問題掂榔。這是C語言程序設(shè)計(jì)練習(xí)題中比較常見的一道題,今天我們將通過多種解法幫助大家熟悉C語言程序設(shè)計(jì)的基本思想酥泛。請(qǐng)大家跟隨我的思路一步步練習(xí)月趟,程序設(shè)計(jì)中解決問題的思路才是最珍貴的。
1. 題目分析
上面這張圖就是楊輝三角撇簿,相信大家在中學(xué)數(shù)學(xué)課中學(xué)習(xí)過聂渊。它實(shí)際上是二項(xiàng)式(a + b)的n次方展開后各項(xiàng)的系數(shù)排成的三角形,它有如下特點(diǎn):
- 每行左右兩邊都是1
- 從第二行起四瘫,中間的每一個(gè)數(shù)是上一行里相鄰兩個(gè)數(shù)之和
- 第n行有n個(gè)數(shù)字
2. 解法一
看到這個(gè)問題汉嗽,最容易想到的是創(chuàng)建一個(gè)二維數(shù)組。之后像填表一樣把每一行的數(shù)據(jù)依次填進(jìn)二維數(shù)組中找蜜。如圖所示:
2.1 二維數(shù)組初始化
首先饼暑,我們需要?jiǎng)?chuàng)建一個(gè)二維數(shù)組(我們以10 * 10的二維數(shù)組為例),全部元素初始化為0洗做,之后把所有1的位置填上弓叛。代碼如下:
# define MAX 10
int main()
{
int i, j, n = MAX;
int array[MAX][MAX] = { 0 };
for (i = 0; i < n; i++)
{
array[i][0] = 1;
array[i][i] = 1;
}
// 打印二維數(shù)組中的三角形
for (i = 0; i < n; i++)
{
for (j = 0; j <= i; j++)
printf("%5d", array[i][j]);
printf("\n");
}
}
執(zhí)行結(jié)果:
這段代碼中需要注意:
- 用宏MAX定義數(shù)組長(zhǎng)度,方便改寫
- 數(shù)組初始化為0
- 打印時(shí)使用“%5d”竭望,防止后面數(shù)字位數(shù)太多破壞打印格式
2.2 計(jì)算剩余單元格
代碼如下:
for (i = 2; i < n; i++)
for (j = 1; j < i; j++)
array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
這段代碼中需要注意:
- 從第三行開始計(jì)算(i = 2)
- 每一個(gè)空格的內(nèi)容都是它左上方和上方兩個(gè)元素之和
2.3 最終結(jié)果
于是我們得到了完整的程序:
# define MAX 10
int main()
{
int i, j, n = MAX;
int array[MAX][MAX] = { 0 };
for (i = 0; i < n; i++)
{
array[i][0] = 1;
array[i][i] = 1;
}
for (i = 2; i < n; i++)
for (j = 1; j < i; j++)
array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
// 打印二維數(shù)組中的三角形
for (i = 0; i < n; i++)
{
for (j = 0; j <= i; j++)
printf("%5d", array[i][j]);
printf("\n");
}
return 0;
}
執(zhí)行結(jié)果如下:
最終打印形式和楊輝三角還有距離邪码,請(qǐng)大家自己思考一下,如何把這些數(shù)字打印成標(biāo)準(zhǔn)的楊輝三角格式咬清。
這個(gè)解法是最樸素的方法闭专,一般大家都能想到。我們要做的只是把這個(gè)方法用代碼實(shí)現(xiàn)而已旧烧。在真正的程序設(shè)計(jì)工作中影钉,往往都是這樣先相處樸素解法,之后再分析哪些環(huán)節(jié)可以優(yōu)化掘剪。下面我們就看看這個(gè)方法能否優(yōu)化平委。
3. 解法二
解法一種兩組for循環(huán)看似比較冗余,我們希望能夠用一組循環(huán)完成所有工作夺谁。
# define MAX 10
int main()
{
int i, j, n = MAX;
int array[MAX][MAX] = { 0 };
for (i = 0; i < n; i++)
{
array[i][0] = 1;
for (j = 1; j <= i; j++)
array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
}
// 打印二維數(shù)組中的三角形
for (i = 0; i < n; i++)
{
for (j = 0; j <= i; j++)
printf("%5d", array[i][j]);
printf("\n");
}
return 0;
}
執(zhí)行結(jié)果完全相同廉赔。此解法把填寫數(shù)字1的工作放入循環(huán)中肉微,減少了一個(gè)循環(huán)。
4. 解法三
解法二中的兩組循環(huán)其實(shí)都是對(duì)二維數(shù)組的遍歷蜡塌,第一遍填數(shù)字碉纳,第二遍打印。那我們能不能一次遍歷就完成既填空又打印的動(dòng)作呢馏艾。請(qǐng)看下面這段代碼:
# define MAX 10
int main()
{
int i, j, n = MAX;
int array[MAX][MAX] = { 0 };
for (i = 0; i < n; i++)
{
array[i][0] = 1;
printf("%5d", 1);
for (j = 1; j <= i; j++)
{
array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
printf("%5d", array[i][j]);
}
printf("\n");
}
return 0;
}
同樣的功能劳曹,這樣實(shí)現(xiàn)是否又簡(jiǎn)潔了一些呢?
5. 解法四
解法三還能優(yōu)化嗎琅摩?當(dāng)然可以铁孵,我們最終的目的是打印,并非保存房资,那么我們其實(shí)沒有必要用一個(gè)二維數(shù)組把所有的數(shù)字保存起來蜕劝。我們只需要在打印的時(shí)候讀取上一行的內(nèi)容,同時(shí)計(jì)算出當(dāng)前行內(nèi)容保存起來即可轰异。那么我們?cè)囍脙蓚€(gè)一維數(shù)組來完成熙宇。
# define MAX 10
int main()
{
int i, j, n = MAX;
// 兩個(gè)數(shù)組用來保存兩行數(shù)字
int array1[MAX] = { 0 };
int array2[MAX] = { 0 };
int* pUp = array1; // 指向保存上一行數(shù)字的數(shù)組
int* pDown = array2; // 指向保存當(dāng)前行數(shù)組的數(shù)組
int* p = NULL; // 空指針用來進(jìn)行指針交換
int index = 0; // 訪問下標(biāo)
for (i = 0; i < n; i++)
{
printf("%5d", 1);
*(pDown + index++) = 1;
for (j = 1; j <= i; j++)
{
*(pDown + index) = *(pUp + index - 1) + *(pUp + index);
printf("%5d", *(pDown + index));
index++;
}
index = 0;
// 兩個(gè)指針指向內(nèi)容交換
p = pUp;
pUp = pDown;
pDown = p;
printf("\n");
}
return 0;
}
這段代碼的執(zhí)行效率很高,存儲(chǔ)空間使用的也比較少溉浙。但可讀性相對(duì)差一些。我們用了兩個(gè)數(shù)組array1和array2蒋荚,又用了兩個(gè)指針來管理這兩個(gè)數(shù)組戳稽。為什么不直接用數(shù)組名操作呢,因?yàn)閮蓚€(gè)數(shù)組的使用時(shí)交替進(jìn)行的期升,一個(gè)保存當(dāng)前行惊奇,一個(gè)保存上一行。
這個(gè)解法難度比較大播赁,初學(xué)者可以先不做了解颂郎。如果留言中需要具體講解的人數(shù)多,我會(huì)在下一篇中重點(diǎn)講解容为。
程序設(shè)計(jì)千變?nèi)f化乓序,這道題也遠(yuǎn)不止這四種解法。請(qǐng)大家在學(xué)習(xí)這四種的同時(shí)自己思考新的方法坎背。
6. 課后練習(xí)
今天的課后練習(xí)題出個(gè)簡(jiǎn)單的替劈,請(qǐng)編程打印出9*9乘法表。
最后得滤,我想說這個(gè)專題重在訓(xùn)練而不在講解陨献。如果只看講解不做練習(xí),那么提高的空間將會(huì)非常有限懂更。
我是天花板眨业,讓我們一起在軟件開發(fā)中自我迭代急膀。
如有任何問題,歡迎與我聯(lián)系龄捡。
上一篇:21天C語言代碼訓(xùn)練營(yíng)(第二天)
下一篇:21天C語言代碼訓(xùn)練營(yíng)(第四天)