选题原因
今天上课老师提出了一个问题,让我们用c语言来打印一个菱形,我觉得很有趣,分享给大家.
题目
输入一个数字n,在控制台输出一个n行的菱形,例如
输入3
*
***
*
输入4:
*
***
***
*
输入5
*
***
*****
***
*
这个题不难,但是老师问我们如何在尽量少的层数循环下实现,
老实说我刚开始想用二重循环,上下两个三角打印,但是听说有使用一重循环的解法,我就重新思考了一下
思路
对于我们的任意输入来说,我们的每行的字符数量(包括" ")是固定的且都是不大于输入的奇数,例如我们输入5来说,我们每行的字符都是5个
从打印的"*""入手来说,考虑每行打印"*"的数量,我发现每行数量+2,在铺满后每行-2
但是这样做最大的问题是,当我们的输入是一个偶数时,无法做到打印两个满行
这时候我想到,如果决定我打印多少星号的并不是一个准确的值,而是一个范围,那么当我输入一个偶数时打印两个满行是否可以实现
我下意识的找数字0作为一个边界,在0周围的数字范围对应最中间的几行,这是我发现以每行开头的空格数来计算是最方便的
这时我如果去掉每行最中间的"*",图形会变成一个可以分割的,对称的图形,如
输入5
2,2
** 1,1
**** 0,0
** 1,1
2,2
每行的前面的空格数是递减的,我前面也说要找到一个范围,让计算机去帮我们判断
根据整型(正的)变量除法的特性,我们知道计算结果是一个向下取整的整数
我在想能不能找到数量关系,让输入为奇数的时候,最中间行的"*"数量为0,输入为偶数时中间两行"*"个数是小于1的(通过除法结果为0)
实现
输入为n
每行的字符个数为m = n%2==0?n-1:n;(不大于n的整数)
当前行数为i (不会有人不知道程序员数数是从0开始数的吧)
空格数通过观察为abs((n-1-2*i)/2 ) (整型变量)
当输入为奇数时,最中间行为i=(n-1)/2,代入空格数的表达式结果为0
输入为偶数时,中间的两行为n/2-1和n/2代入空格的表达式结果为+-0.5,绝对值取整都是0,刚好符合
代码
#include <stdio.h>
#include <stdlib.h>
void function();
void printLine(int l, int n);
int main(void) {
int n;
scanf("%d", &n);
function(n);
}
void function(int n) {//函数定义
int m = n % 2 == 0 ? n - 1 : n;
for (int i = 0; i < n; ++i) {
printLine(m, abs(n - 1 - 2 * i) / 2);
}
}
void printLine(int l, int n) {
for (int i = 0; i < n; ++i) {
printf(" ");
}
for (int i = 0; i < l - 2 * n; ++i) {
printf("* ");
}
for (int i = 0; i < n; ++i) {
printf(" ");
}
printf("\n");
}
为了更美观,输出更像正方形,我在"*"输出的时候加了空格,可以去掉