相信学习编程的,大多都做过下面或者类似下面的这样一道题:
打印如下图案:
★
★★
★★★
★★★★
★★★★★
不管使用什么高级编程语言,都能很轻松地使用二重循环完成对该图形的打印,例如想使用C#语言在控制台程序实现, 可以在程序主函数里面这样写:
1 for (int i = 1; i <= 5; i++) 2 { 3 for (int j = 1; j <= i; j++) 4 { 5 Console.Write(‘★‘); 6 } 7 Console.WriteLine(); 8 } 9 Console.ReadKey();
或者使用while二重循环:
1 int i = 1; 2 int j = 1; 3 while (i <= 5) 4 { 5 j = 1; 6 while (j < i) 7 { 8 Console.Write("★"); 9 j += 1; 10 } 11 Console.WriteLine("★"); 12 i += 1; 13 } 14 Console.ReadKey();
但是大家有没有尝试用SQL语句写过呢?如果你按照上面方法的思路直接写或许会遇到一些问题。打开SQL Server Management Studio,登录进去后新建查询,在这里写SQL语句完成上面的题目。首先我按上面思路照着写了一个:
1 declare @i int=1 2 declare @j int=1 3 while(@i<=5) 4 begin 5 set @j=1 6 while(@j<@i) 7 begin 8 print‘★‘ 9 set @j+=1 10 end 11 print‘★‘ 12 --print Char(10) 13 set @i+=1 14 end
在第12行,问题来了,C#Write()不换行,WriteLine()换行,能实现精确控制,但是SQL的“print”方法输出是默认换行的,如果我不加上print Char(10) (Char(10)代表换行键,也可以用Char(13)回车键代替,下同),那么执行结果便是只有一列,每行一个“★”,共有1+2+3+4+5=15行。如果我加上print Char(10),执行结果还是一列,只不过会按照第一行一个星,空两行,然后连续两行一个星,又空两行,然后又连续三行一个星这样的顺序排列下去。当然这样并没有达到我们原先题目的要求。要想达到题目要求,我们可以考虑定义一个字符串变量来存储“★”字符串,然后在循环的时候输出并累加一个“★”,如下所示:
1 declare @i int=1 2 declare @outstring nvarchar(5)=‘‘ 3 while(@i<=5) 4 begin 5 set @outstring+=‘★‘ 6 print @outstring 7 set @i+=1 8 end
这样就OK了。下面再介绍几种方式。
这种是添加完所有字符串(含换行符)再输出的:
1 declare @i int=1 2 declare @j int=1 3 declare @outstring nvarchar(19)=‘‘ 4 while(@i<=5) 5 begin 6 set @j=1 7 while(@j<=@i) 8 begin 9 set @outstring+=‘★‘ 10 set @j+=1 11 end 12 set @outstring+=Char(10) 13 set @i+=1 14 end 15 print @outstring
这种是添加完所有字符串(没含换行符)再输出的:
1 declare @i int=1 2 declare @j int=1 3 declare @outstring nvarchar(15)=‘‘ 4 while(@i<=5) 5 begin 6 set @j=1 7 while(@j<=@i) 8 begin 9 set @outstring+=‘★‘ 10 set @j+=1 11 end 12 set @i+=1 13 end 14 declare @index int=1 15 declare @start int=1 16 while(@index<=5) 17 begin 18 print substring(@outstring,@start,@index) 19 set @index+=1 20 set @start=@start+@index-1 21 end
这种方式用到了数据库的截取字符串函数。substring()的第三个参数指定子字符串的长度,在这里等于变量@index的值。
这种是已知星星个数,直接按样式输出:
1 declare @i int=1 2 declare @outstring nvarchar(15)=‘‘ 3 while(@i<=15) 4 begin 5 set @outstring+=‘★‘ 6 set @i+=1 7 end 8 declare @index int=1 9 declare @start int=1 10 while(@index<=5) 11 begin 12 print substring(@outstring,@start,@index) 13 set @index+=1 14 set @start=@start+@index-1 15 end
这种是已知星星行数,直接按样式输出:
1 declare @i int=1 2 declare @outstring nvarchar(5)=‘‘ 3 while(@i<=5) 4 begin 5 set @outstring+=‘★‘ 6 print @outstring 7 set @i+=1 8 end
还有一种取巧的方式,大家应该注意到我定义@outstring时分配的大小是不一样的,有的是nvarchar(5),有的是nvarchar(15),还有的是nvarchar(19),实际上这是满足条件的最小值。当你设置的数字比这个数字大的时候,没事;当你设置的数字比这个数字小的时候,也不会报错,但是会显示不全。如果定义一个变量,在赋值的时候赋予了比长度更多的字符串,那么就会产生截断,但是不会报错,这是SQL的特性。本来这是我们应当注意的一个点,但我们也可以利用这个特性,写出“伪完成”的代码。例如将上面一段“添加完所有字符串(含换行符)再输出”的代码做如下改动:
1 declare @i int=1 2 declare @j int=1 3 declare @outstring nvarchar(19)=‘‘ 4 while(@i<=10)--改变循环次数 5 begin 6 set @j=1 7 while(@j<=@i) 8 begin 9 set @outstring+=‘★‘ 10 set @j+=1 11 end 12 set @outstring+=Char(10) 13 set @i+=1 14 end 15 print @outstring
本来while循环条件改成@i<=10,将会输出10行,但是由于只分配了19(15个“★”+4个换行键)个字符的长度,超出的部分就被截断,所以打印出来的效果还是能够符合题目的要求。如果改成分配26个字符的长度,就可以完整地输出六行,如果改成分配34个字符的长度,就可以完整地输出七行,以此类推,直到把所有(10行)全部输出为止。实际运用只需要一种方便且易扩展的就好了,像这种取巧的方式慎用,仅供娱乐。
用不同的方法解题可以锻炼思维,加深对知识本质的理解,希望大家能够从中获得启发,活学活用。
使用SQL语句打印直角三角形五角星阵的N种方法