【问题标题】:Requesting assistance with embedded for loops in C++请求 C++ 中嵌入式 for 循环的帮助
【发布时间】:2020-05-11 07:23:56
【问题描述】:

我目前正在从事一个 CS 课程的项目,我的任务是打印出建筑物的 ASCII 模型。该项目的目标是允许用户输入一个整数并将该整数作为建筑物的“部分”数量。下面我将给我的例子分解成几个部分。任何帮助将不胜感激,感谢任何花时间阅读本文的人。

模式如下。第 x = ((x * 2) + 2) = 代码行数和建筑物的“宽度”。 (x = 任何整数值)

  |\/|
  |/\|                //section 0      ((section * 2) + 2)
  /--\                                   0 + 2 = 2


 |\::/|
 |:\/:|               //section 1      ((section * 2) + 2)
 |:/\:|                                  2 + 2 = 4
 |/::\|
 /----\


|\::::/|
|:\::/:|
|::\/::|              //section 2       ((section * 2) + 2)
|::/\::|                                  4 + 2 = 6
|:/::\:|
|/::::\|
/------\

我设法弄清楚了这种模式,但是很难将多个循环相互嵌入。到目前为止,我所拥有的这座建筑的最佳代表就是这个。

int i = 0;
int j = 0;
int size = 2;
int sizeAdj = (size * 2) + 2;
int leftMost = sizeAdj;


for(i = 0; i <= size; i++){
        for(j = 0; j < 1; j++){
            cout<<setw(leftMost + 1)<<"|";
            cout<<"\\";
            cout<<"/";
            cout<<"|";
            cout<<endl;
            for(j = 0; j < 1; j++){
                cout<<setw(leftMost + 1)<<"|";
                cout<<"/";
                cout<<"\\";
                cout<<"|";
     }
     leftMost = leftMost - 1;
    }
    cout<<endl;
}

这会打印出以下内容。

  |\/|
  |/\|
 |\/|
 |/\|
|\/|
|/\|

再次感谢您。

【问题讨论】:

  • 1.该示例似乎不正确:高度和宽度不同。 2. 您可以使用填充有: 的方形数组,替换边框和对角线,最后逐行打印 - 无需嵌套、混乱的循环。
  • @TheFailurebyDesign 澄清 1. 我没有计算底部“层”,因为我认为这将是一个独立的循环。至于2.我不知道该怎么做,你能进一步解释一下吗?感谢您的评论!
  • @user4581301 我能够使用两个 for 循环打印一个盒子,这就是盒子的“进化”。我不知道如何在每个片段中旋转“上层”和“下层”而不是一个接一个地重复它们。我想我可能不得不在字符之间使用 setw() 来修改间距,但我什至不想考虑这一点。感谢您的评论!
  • 我很抱歉。我将这些部分误读为不同的测试运行,并没有意识到这是一栋建筑在上升时会聚在一起。
  • @user4581301 不用担心! :)

标签: c++ loops for-loop while-loop ascii


【解决方案1】:

说实话,我没有在您的代码中看到这种模式。

开始更简单。首先不要担心前面的空间:

|\/|
|/\|                //section 0      ((section * 2) + 2)
/--\                                   0 + 2 = 2


|\::/|
|:\/:|               //section 1      ((section * 2) + 2)
|:/\:|                                  2 + 2 = 4
|/::\|
/----\


|\::::/|
|:\::/:|
|::\/::|              //section 2       ((section * 2) + 2)
|::/\::|                                  4 + 2 = 6
|:/::\:|
|/::::\|
/------\

如果你有,你只需要在前面添加x 空格。

接下来,当我们添加“假”线时,对称性更加明显:

\----/
|\::/|
|:\/:|               //section 1      ((section * 2) + 2)
|:/\:|                                  2 + 2 = 4
|/::\|
/----\ 

现在宽度和高度是一样的,我们可以使用

int width(int x) { return (x*2)+2; }

编写一个函数,返回给定位置的正确字符

char get_simple_pattern(int x,int row,int col) {
     if (row == col) return '\\';
     // ...
     return ':';
}

使用两个循环来打印它

void print_simple_pattern(int x) {
   for (int row=0; row < width(x); ++row) {
       for (int col=0; col < width(x); ++col) {
           std::cout << get_simple_pattern(x,row,col);
       }
       std::cout << "\n";
   }
}

一旦你有这个正确的,你必须

  • 在每行前面添加x 空格:std::cout &lt;&lt; std::string(x,' ');
  • 跳过第一行
  • x 上添加一个循环

【讨论】:

    【解决方案2】:

    但我很难将多个循环相互嵌入。

    从表面上看,您很难编写有效的循环,直到您尝试嵌套它们时才注意到。看看使用j 作为循环控制变量的循环:

    for(j = 0; j < 1; j++)
    

    从技术上讲,这是一个循环语句。但是,它将j 设置为0,运行循环一次,然后将j 递增到1 并退出循环。当总是只有一次迭代时,很难认为这是一个真正的循环。如果您跳过for 语句而只设置j = 0,您的计算机工作就会减少。

    不过,嵌套循环的方式存在问题。您的循环结构(忽略循环体中的其他语句)如下。

    for(i = 0; i <= size; i++){
        for(j = 0; j < 1; j++){
            for(j = 0; j < 1; j++){
    

    注意中间和最里面的循环都使用j?那是一场等待发生的灾难。不要让嵌套循环与包含循环的循环控制变量混为一谈。


    更好的是,尽量避免嵌套循环。考虑一下您希望循环的每次迭代发生什么,然后将该功能委托给不同的函数。例如,您的最外层循环可能如下所示:

    for(i = 0; i <= size; i++)
        printSection(i, size);
    

    然后您可以编写一个printSection 函数来处理建筑物的每个部分。这将是您的中间循环的意图,对吗? (如果没有,请调整细节以符合您的意图。关键是要避免将大量步骤混杂在一块代码中。)您可以轻松地自行测试此功能。例如,让您的 main 函数调用 printSection(1,2); 而不是使用循环,并确保输出与您的问题描述中的内容相匹配。重复printSection(2,2); 和其他尽可能多的示例,以确保此功能按预期工作。

    // Print section number `section` for a building with `size` sections.
    void printSection(int section, int size)
    {
        for(int i = 0; i <= section; i++) {
            // Handle the indent here, since it is the same throughout the section.
            cout << setw(size - section) << ' ';
            // Delegate the floor details to another function.
            printFloor(i, section);
            // End the line. Alternatively, this could be delegated to printFloor.
            cout << '\n';
        }
    }
    

    您可能会注意到我在两个循环中都使用了i。我不是说有问题吗?如果循环是直接嵌套的。但是,它们在不同的功能中,所以没问题。

    接下来,您将编写printFloor 函数。我会 从简单开始; printFloor(int floor, int section) 最初只写一个管道字符 ('|'),然后是 2*section + 2 冒号,然后是另一个管道字符。一旦你开始工作,你就可以担心穿过建筑物的X。从小处着手,分而治之,并确保每个部分都能正常工作,然后再将它们组合在一起。

    【讨论】:

      【解决方案3】:

      我在 C 语言中这样做是为了好玩.... 不管它的价值如何:

      #include <stdio.h>
      #include <string.h>
      
      void print_section(int n, int z)
      {
          char dots[2*n+1];
          memset(dots,':',2*n+1);
          dots[2*n+1]=0;
          for(int r=0;r<n+1;++r)
          {
              printf("%*.s|%.*s\\%.*s/%.*s|\n",z-n,"",r,dots,2*(n-r),dots,r,dots);
          }
      
          for(int r=n;r>=0;--r)
          {
              printf("%*.s|%.*s/%.*s\\%.*s|\n",z-n,"",r,dots,2*(n-r),dots,r,dots);
          }
          memset(dots,'-',2*(n+1));
          printf("%*.s/%.*s\\\n",z-n,"",2*(n+1),dots);
      }
      
      int main(void) {
          int sections;
          printf("Please enter number of sections: \n");
          scanf("%d", &sections);
      
          for(int s=0; s<sections; ++s)
          {
              print_section(s, sections);
          }
      
          return 0;
      }
      

      输出

      5 个部分

      Success #stdin #stdout 0s 4276KB
      Please enter number of sections:  5
           |\/|
           |/\|
           /--\
          |\::/|
          |:\/:|
          |:/\:|
          |/::\|
          /----\
         |\::::/|
         |:\::/:|
         |::\/::|
         |::/\::|
         |:/::\:|
         |/::::\|
         /------\
        |\::::::/|
        |:\::::/:|
        |::\::/::|
        |:::\/:::|
        |:::/\:::|
        |::/::\::|
        |:/::::\:|
        |/::::::\|
        /--------\
       |\::::::::/|
       |:\::::::/:|
       |::\::::/::|
       |:::\::/:::|
       |::::\/::::|
       |::::/\::::|
       |:::/::\:::|
       |::/::::\::|
       |:/::::::\:|
       |/::::::::\|
       /----------\
      

      【讨论】:

      • 这实际上有很大帮助!我需要看到事物的“流程”,虽然我从来没有用 C 编程过,但我想我知道发生了什么。我要回到生产力洞穴(我的办公室)尝试一些新事物,感谢您的回复!
      • 如果你想要 C,为什么要标记 [C++]?
      • 我不想要 C,但它是我提供的,我仍然感谢您的响应。 C 和 C++ 非常相似,即使我需要查找一些东西,我也有相当的理解。
      • 从长远来看,纯代码的答案往往没有用,在短期内也往往没有用。
      • @GeorgiN 您可以在这里使用的一种策略是选择一个问题区域,最好是一个可以帮助您理解其他部分的区域,然后提出一个新问题。使用调试器来单步调试代码以观察它的作用也是一件好事。如果你不知道它是怎么做的,这里使用的 C 函数有非常好的文档记录(它们应该是在将近 50 年后)。留下问题的地方,问一个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-21
      相关资源
      最近更新 更多