namespace SquareStars
{
class Program
{
static void Main(string[] args)
{
var n = int.Parse(Console.ReadLine());
for (int i = 0; i <n-1; i++)
{
Console.Write("*");
}
for (int i = 0; i < n-1; i++)
{
Console.WriteLine("*");
}
for (int i = 0; i < n; i++)
{
Console.Write("*");
}
}
}
}
我的练习就是做这样的星形广场: 取决于“n”。我尝试使用for循环,但我可以做正方形的右侧。 我这样做:
***
*
***
但我想要这个:
*** ****
* * * *
*** or * *
****
可以帮我这个代码????
答案 0 :(得分:2)
以下内容应该:
public static string CreateASCIISquare(int squareSideLength, char c = '*')
{
if (squareSideLength < 1)
return "";
if (squareSideLength == 1)
return c.ToString();
var horizontalOuterRow = new String(c, squareSideLength);
var horizontalInnerRow = $"{c}{new string(' ', squareSideLength - 2)}{c}";
var squareBuilder = new StringBuilder();
squareBuilder.AppendLine(horizontalOuterRow);
for (int i = 0; i < squareSideLength - 2; i++)
{
squareBuilder.AppendLine(horizontalInnerRow);
}
squareBuilder.Append(horizontalOuterRow);
return squareBuilder.ToString();
}
好的,让我们解释一下代码:
始终验证进入方法的数据。在您的情况下,用户可以指定正方形的长度。有无效值吗?很明显是的,-2
似乎不是一个有效的选择。
这里有很多选择。您可以告诉用户该值无效,您可以简单地忽略它,不做任何事情,让您的应用程序崩溃并惨死,或者您可以返回一个空方块。所有都是有效的选择,但有意识地选择一个并根据您的决定进行设计。在我的情况下,我选择返回一个空方块:
if (squareSideLength < 0)
return "";
在没有for
循环和Console.Write
等的情况下,我是否可以轻松管理?是的,长度0
和1
似乎非常简单。按理说,如果我将空方块返回负值,我会对0
大小的方块执行相同操作。所以我将以前的代码更改为:
if (squareSideLength < 1)
return "";
好,那现在1
呢?那也很容易,不是吗?
if (squareSideLength == 1)
return c.ToString();
故事的道德:首先处理无效数据或琐碎案件。很多时候,琐碎的案件也可能是一些可能使您的一般解决方案复杂化的问题,快速将它们排除在外!
好的,现在让我们考虑一个方块的样子:
**
**
***
* *
***
****
* *
* *
****
这种模式似乎非常明显。一个正方形由两行组成,其中包含指定数量的星号,0
或更多行仅包含2颗星和squareSideLength - 2
个空格。好吧,它只有两种类型的行,让我们预先构建它们:
var horizontalOuterRow = new String(c, squareSideLength);
var horizontalInnerRow = $"{c}{new string(' ', squareSideLength - 2)}{c}";
大!我们得到了构建块,现在让我们构建我们的广场:
那怎么回事?好吧,我们首先添加horizontalOuterRow
然后添加squareSideLength - 2
horizontalInnerRow
,然后我们再添加一个horizontalOuterRow
。
瞧,我们得到了一个漂亮的小ASCII方块:
squareBuilder.AppendLine(horizontalOuterRow);
for (int i = 0; i < squareSideLength - 2; i++)
{
squareBuilder.AppendLine(horizontalInnerRow);
}
squareBuilder.Append(horizontalOuterRow);
我使用StringBuilder
的事实与这个问题没有密切关系,但是在构建动态构建的字符串时,养成使用此工具的习惯,你不知道事先的长度。连接字符串会给你带来非常糟糕的性能,所以最好尽可能避免它。
现在我们自豪地将我们漂亮的ASCII广场还给我们的超级用户,并在掌声的鼓掌下晒太阳:
return squareBuilder.ToString();
希望这个小答案可以帮到你。
请记住,要编写好代码,将所有内容分解为非常小的任务,并一次一个地处理它们。想想你是如何手工完成它并以这种方式编写的。一旦你有工作,就有时间看你是否需要优化,重构等代码。但关键是让它尽可能清晰地使用代码。
答案 1 :(得分:2)
You can use the string(char, int)
constructor to create strings of repeating characters. This lets you simplify the code to use a single for
loop:
var n = int.Parse(Console.ReadLine());
Console.WriteLine(new string('*', n));
for (int i = 0; i < n - 2; i++)
{
Console.WriteLine("*" + new string(' ', n - 2) + "*");
}
Console.WriteLine(new string('*', n));
答案 2 :(得分:0)
class Program
{
static void Main(string[] args)
{
var n = int.Parse(Console.ReadLine());
for (int row = 1; row <= n; row++)
{
for (int col = 1; col <= n; col++)
{
if (row == 1 || row == n)
{
Console.Write("*");
}
else
{
if (col == 1 || col == n)
{
Console.Write("*");
}
else
{
Console.Write(" ");
}
}
}
Console.WriteLine();
}
Console.ReadKey();
}
}
答案 3 :(得分:0)
您可以在第二个循环中更改Console.WriteLine
,如下所示:
class Program
{
static void Main(string[] args)
{
var n = int.Parse(Console.ReadLine());
for (int i = 0; i < n - 1; i++)
{
Console.Write("*");
}
for (int i = 0; i < n - 1; i++)
{
Console.WriteLine(i == 0 ? "*" : "*" + string.Empty.PadLeft(n - 2) + "*");
}
for (int i = 0; i < n; i++)
{
Console.Write("*");
}
}
}