字符三角形系列——数列与函数变换

一、准备知识

  1:根据数列的前有限项归纳通项公式(主要是直线型),也可以说是一次函数的运用。

  2:坐标平移。把函数y=f(x)的图像向右平移m个单位可得到y=f(x-m)的图形,把函数y=f(x)的图像向上平移n个单位可得到函数y=f(x)+n的图像

  3:对称变换。把函数y=f(x)的图像沿直接x=m对称可得到函数y=f(2m-x)的图像,把函数y=f(x)的图像沿y=n对称后可得到2n-y=f(x)的图像

  4:翻折变换。把函数y=f(x)的图像中y轴左边部分清除,把右边图像沿y轴对称到左边,右边图像依然保留,把函数y=f(x)的图像中x轴下边部分清除,把上边图像沿x轴对称到下边,上边图像依然保留

二、字符三角形示例

1:输出下图字符三角形,其中字符可变,行数也可变。

*
**
***
****
*****
******

  本例较为简单,首先确定行数,逐行输出——一个循环可解决。每一行的字符个数在变,容易看出跟行数有关——就等于行号,故而整个输出就一个双循环可搞定,代码如下

#include<iostream>
using namespace std;
int main(){
    int a=6;
    char ch='*';
    for(int y=1;y<=a;y++)
    {
        for(int x=1;x<=y;x++)
            cout<<ch;
        cout<<endl;
    }
    return 0;
}
square1

 2:输出下图字符三角形

******
*****
****
***
**
*

  这个问题跟上一个问题类似,只是每一行的字符个数逆序而己。实现方法就是改变内循环总次数,而这个次数其实就是一个关于行号的函数,也可以说是一个数列的通项公式。当然也可是跟第一个问题类似的处理办法,只是一个取前段,一个取后段。两个思路的代码如下

#include<iostream>
using namespace std;
int main(){
    int a=6;
    char ch='*';
    for(int y=1;y<=a;y++)
    {
        for(int x=y;x<=a;x++)
            cout<<ch;
        cout<<endl;
    }
    return 0;
}
square2-1
#include<iostream>
using namespace std;
int main(){
    int a=6;
    char ch='*';
    for(int y=1;y<=a;y++)
    {
        for(int x=1;x<=a+1-y;x++)
            cout<<ch;
        cout<<endl;
    }
    return 0;
}
square2-2

3:输出下图字符三角形

     *
    **
   ***
  ****
 *****
******

  这个问题可以做个分解,每行分两个部分,前部分是空格,后部分是字符,空格个数参照第二个问题,字符个数参照第一个问题,代码实现应该较为容易。还有一种思路,把整个输出看作是一个aXa方阵,找出空格与字符的分界,用条件判断是输出字符还是空格。为了符合习惯,我们可以把行号转换成纵坐标,把整个分界线看作一个函数的图像(部分)。代码如下

#include<iostream>
using namespace std;
int main(){
    int a=6;
    char ch='*';
    for(int y=1;y<=a;y++)
    {
        for(int x=y+1;x<=a;x++)
            cout<<' ';
        for(int x=1;x<=y;x++)
            cout<<ch;
        cout<<endl;
    }
    return 0;
}
square3-1
#include<iostream>
using namespace std;
int main(){
    int a=6,x,y;
    char ch='*';
    for(int i=1;i<=a;i++)
    {
        y=a+1-i;//用于转换坐标系 
        for(x=1;x<=a;x++)
        {
            if(y>x)cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square3-2

4:输出下图字符三角形

     *
    ***
   *****
  *******
 *********
***********

  按照前面的经验,如果把每一行分成两个部分,那这个问题也不难,前面是空格,跟第三个问题差不多,字符个字数嘛,不难看出就是奇数,其通项公式很容易得出第n行的个数是2n-1。

  当然也可以看作第一个问题的图像沿y轴翻折而成,根据前面所述,每一行的数字可以是-a到a。如果不喜欢负数,也可以向右平移a单位,其代码如下

#include<iostream>
using namespace std;
int main(){
    int a=6;
    char ch='*';
    for(int y=1;y<=a;y++)
    {
        for(int x=y+1;x<=a;x++)
            cout<<' ';
        for(int x=1;x<=y*2-1;x++)
            cout<<ch;
        cout<<endl;
    }
    return 0;
}
square4-1
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=5,x,y;
    char ch='*';
    for(int i=0;i<=a;i++)
    {
        y=a+1-i;//用于转换坐标系 
        for(x=-a;x<=a;x++)
        {
            if(y>a+1-abs(x))cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square4-2
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=5,x,y;
    char ch='*';
    for(int i=0;i<=a;i++)
    {
        y=a+1-i;//用于转换坐标系 
        for(x=0;x<=a*2;x++)
        {
            if(y>a+1-abs(x-a))cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square4-3

5:输出下图字符三角形

      *
     ***
    *****
   *******
  *********
 ***********
 ***********
  *********
    *******
     *****
      ***
       *

  这个问题可以分上下两部分,这个方法就不再做了,我们完全可以做上下翻折变换,当然也可以通过平移稍做改变,实现代码如下

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=6,x,y;
    char ch='*';
    for(int i=-a;i<=a;i++)
    {
        y=abs(i);
        for(x=0;x<y;x++)
            cout<<' ';
        for(x=1;x<=(a-y)*2+1;x++)
            cout<<ch;
        cout<<endl;
    }
    return 0;
}
square5-1
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=5,x,y;
    char ch='*';
    for(int i=-a;i<=a;i++)
    {
        y=abs(i);//用于转换坐标系 
        for(x=-a;x<=a;x++)
        {
            if(y>a-abs(x))cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square5-2
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=5,x,y;
    char ch='*';
    for(int i=0;i<=a*2;i++)
    {
        y=abs(a-i);//用于转换坐标系 
        for(x=0;x<=a*2;x++)
        {
            if(y>a-abs(x-a))cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square5-3

6:输出以下图像

     *         *
    ***       ***
   *****     *****
  *******   *******
 ********* *********
*********************

  这个例子可以说简单,就是把第四个示例的图像对称一下就好,你知道对称轴吗?代码如下

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=5,x,y;
    char ch='*';
    for(int i=0;i<=a;i++)
    {
        y=a-i;//用于转换坐标系 
        for(x=-2*a;x<=a*2;x++)
        {
            if(y>a-abs(abs(x)-a))cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square6-1
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=5,x,y;
    char ch='*';
    for(int i=0;i<=a;i++)
    {
        y=a-i;//用于转换坐标系 
        for(x=0;x<=a*4;x++)
        {
            if(y>a-abs(abs(a*2-x)-a))cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square6-2

7:输出以下图像

  这个示例只是用了两个字符,形成中间的两个菱形字符,可以是第6个示例的纵向翻折,也可以是第5个示例的横向对称,代码如下

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=6,x,y;
    char ch='O';
    for(int i=0;i<=a*2;i++)
    {
        y=abs(a-i);//用于转换坐标系 
        for(x=-2*a;x<=a*2;x++)
        {
            if(y>a-abs(abs(x)-a))cout<<'H';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square7-1
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a=6,x,y;
    char ch='+';
    for(int i=0;i<=a*2;i++)
    {
        y=abs(a-i);//用于转换坐标系 
        for(x=0;x<=a*4;x++)
        {
            if(y>a-abs(abs(a*2-x)-a))cout<<' ';
            else cout<<ch;
        }
        cout<<endl;
    }
    return 0;
}
square7-2

  小结:算法终究是离不开数学的,好的算法是建立在好的数学思维之上的,开动脑筋,不僵化就会有好的算法。以上内容仅供参考,如有不妥请指教。

原文地址:https://www.cnblogs.com/wendcn/p/13445556.html