【问题标题】:How should I modify this code to print a diamond pattern using the letters from a given string?我应该如何修改此代码以使用给定字符串中的字母打印菱形图案?
【发布时间】:2020-02-20 19:24:18
【问题描述】:

对于作业,我需要编写一个程序,该程序接受用户输入的字符串并使用给定字符串的字母输出菱形图案。 (不使用数组)。

例如:

> Enter a word: hello
    h
   e e
  l   l
 l     l
o       o
 l     l
  l   l
   e e
    h

我一直无法理解如何为此类事情操作嵌套的 for 循环,因此我尝试获取类似问题的源代码并对其进行修改。

#include <iostream>

using namespace std;

int main()
{
int n,k,c,space=1;
cout<<"Enter the number of Rows..."<<endl;
cin>>n;
space=n-1;
    for(k=1;k<=n;k++)
    {
        for(c=1;c<=space;c++)
        {
            cout<<" ";
        }
        space--;
        for(c=1;c<=2*k-1;c++)
        {
            cout<<"*";
        }
        cout<<endl;
    }
    space=1;
    for(k=1;k<=n;k++)
    {
        for(c=1;c<=space;c++)
        {
            cout<<" ";
        }
        space++;
        for(c=1;c<=2*(n-k)-1;c++)
        {
            cout<<"*";
        }
        cout<<endl;
    }
    return 0;
}

这会打印一个由星号组成的三角形。最初我以为我可以稍微编辑一下变量并使用源代码为我处理间距,但显然因为我真的不明白变量是如何影响问题的,所以我还没有走多远.如果有人能向我解释我应该如何解决这个问题,我将不胜感激。

【问题讨论】:

  • 您可以通过使用调试器了解很多关于您的程序的信息。您可以让调试器执行每一行,一次一个,并显示变量中的值。一个非常方便的了解和使用工具。
  • 我知道我们正在查看您的家庭作业。您的第一个解决方案尝试是搜索执行请求的现有代码,但没有找到任何代码。现在,第二个解决方案尝试要求 StackOverflow 将一些模糊相似的代码转换为回答您作业的代码。我建议第三次尝试编写自己的代码,基于您在课堂上学到的知识、教程并拥有自己的工作。
  • 当您遇到困难时,请看这里,这是最有可能寻求帮助的方法:meta.stackoverflow.com/questions/334822/… 当您处于该阶段时,请确保显示所需输出的文本信息在这里直接作为文本,而不是作为文本图片的链接。
  • @Yunnosch 我并不是专门寻找复制粘贴的情况。如果我了解如何解决问题,我非常愿意(实际上我更喜欢)编写自己的代码。问题是我的教授是一个非常不干涉“自己弄清楚”的教练,我不是这样学习的。因此,让我处于这种我不知道从哪里开始的情况。

标签: c++ string nested-loops


【解决方案1】:

解决此类问题的一种好方法是从图片开始,例如您在问题中链接的图片。现在,对于五个字母的单词“Hello”,您可以从图片中看出 H 位于位置 4 的中心。(请记住,数组和字符串索引从 0 开始。)下一步还要查看其他示例。例如,让我们看看钻石对 3 个字母的单词“cat”的要求。

  c
 a a
t   t
 a a
  c

这一次,字母“c”以位置 2 为中心。做这些示例的目的是找到一个模式;在这里,我们发现模式是第一个字母总是以word length - 1 为中心。因此,在第一个字母的行上有word length - 2 前导空格。

下一行呢?请注意重复字母之间的前导空格和额外的空格是如何减少的。因此,我们有word length - 2 - 1 前导空格和1 空格分隔它们。

第三行呢?现在我们在字母和word length - 2 - 2 前导空格之间有三个空格。你开始看到一种模式了吗?查看第一个示例(“Hello”)的第四行和第五行,并尝试找出前导空格和字母之间空格的数量。 试一试后阅读以下内容。

每向下一行,我们就会失去一个前导空格。除了第二行,每次我们向下一行,我们还会在字母之间增加两个空格。 现在,你能把这个模式转换成公式吗? 再一次,看看你是否能想出一个公式,然后继续阅读。

我们了解到,前导空格数等于word length - 1 - row(其中row从0开始),字母之间的空格数等于row * 2 - 1。 (注意这个公式如何正确处理第二行的情况。)

因此,您的代码应如下所示:

// Word of caution: I have not tested this code.
using namespace std; // Bad practice in production code; used here for simplicity.
// *snip*
string my_word;
cin >> my_word;
int middle_index = my_word.length() - 1;
for (int r = 0; r < my_word.length; ++r) {
  // This code prints the top part of the diamond.
  for (int ls = 0; ls < middle_index - r; ++ls) {
    cout << " "; // Print out the leading spaces.
  }
  cout << my_word[r]; // You can replace this with my_word.substr(r, 1)
                      // if you are unallowed to treat strings like arrays.
  // r == 0 is a special case since we only print one of those letters.
  if (r == 0) {
    continue;
  }
  // Otherwise, we simply need to print the number of spaces in-between.
  for (int bs = 0; bs < 2 * r - 1; ++bs) {
    cout << " ";
  }
  cout << my_word[r];
}

现在要打印钻石的另一半,您必须执行与上述类似的操作。请记住在word length - 2 开始循环(请参阅您的图片以了解原因)并每次减少循环索引。另外不要忘记r == 0 仍然是一个特例,因为您只打印一次。

【讨论】:

  • 到目前为止这很好,但我忘了提到我不允许使用数组。是否可以使用类似 my_word.substr() 的东西?
  • 在 C++ 中,您可以将字符串视为数组(就像我所做的那样),但它们实际上并不是数组。也就是说,如果您的教授坚持,您可以将my_word[r] 修改为my_word.substr(r, 1)。 (所以是的,你可以使用substr。)
  • @J.Kent 您应该编辑您的问题并包含该信息。
  • @Isaiah 感谢您的帮助,完成了。您的代码没有完全打印正确的格式,但我只需要在这里和那里添加一些“endl”。至于三角形的下半部分,幸运的是在递减时使用相同的代码会产生正确的结果。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多