C ++谷歌开始练习#4

时间:2014-02-14 01:46:08

标签: c++

https://developers.google.com/edu/c++/getting-started#exercises-and-projects

我指的是练习#4 - 横幅

我很难理解这是如何工作的。我为每个字母创建了不同的功能,“F”“R”& “E”。

“F”,例如:

void printF(){
cout<<"FFFFF"<<endl;
cout<<"F"<<endl;
cout<<"FFF"<<endl;
cout<<"F"<<endl;
cout<<"F"<<endl;
}

据我所知,这不起作用,因为没有办法打印这样的东西,然后在它旁边打印另一个。有人可以从概念上解释或提供一个如何打印“免费”一词的例子吗?谢谢

3 个答案:

答案 0 :(得分:2)

您可以将字母创建为std::string数组。为了保持一致性,它是五个字符串,长度为五个字符。您可以使用get_font_letter之类的函数来选择当前字母。有更好的方法可以做到这一点,但如果你只关心这个词,它应该是好的。我建议做一些像“字体数据库”这样的东西,你可以在文本文件中绘制和索引字母。

#include <iostream>
#include <vector>

std::string f[] = {
    "FFFFF",
    "F    ",
    "FFF  ",
    "F    ",
    "F    ",
};

std::string r[] = {
    "RRRRR",
    "R   R",
    "RRRR ",
    "RRR  ",
    "R  RR",
};

std::string e[] = {
    "EEEEE",
    "E    ",
    "EEE  ",
    "E    ",
    "EEEEE",
};

std::string* get_font_letter(const char& c)
{
    if (c == 'F') return f;
    if (c == 'R') return r;
    if (c == 'E') return e;
}

您不需要二维std::vector。你可以用一个空格将每一行拼凑起来。

int main()
{
    std::string word = "FREE";
    std::vector<std::string> v;
    v.resize(5);
    for (unsigned int i = 0; i < 5; i++)
    {
        std::string row = "";
        for (auto it = word.begin(); it != word.end(); ++it)
        {
            auto letter = get_font_letter(*it);
            row += letter[i] + " ";
        }
        v.push_back(row);
    }
    for (auto it = v.begin(); it != v.end(); ++it)
        std::cout << *it << "\n";
}

输出:

FFFFF RRRRR EEEEE EEEEE 
F     R   R E     E     
FFF   RRRR  EEE   EEE   
F     RRR   E     E     
F     R  RR EEEEE EEEEE

答案 1 :(得分:1)

没有给你完整的解决方案,因为你显然需要学习,这将是我的策略:

使用字符串向量(或二维数组)来表示字母。然后构建那些向量的列表来表示字符串并按字符串打印所有向量字符串(打印所有向量的第一个字符串,然后是第二个,等等)。各个字符串应该具有恒定的长度并提供一些间距。

答案 2 :(得分:1)

这就是我在这个例子中所做的。

  1. 首先我想创建一个像printA(),printB()这样的函数,刚才在问题细节中描述。但我意识到同样的问题。此外,这意味着我们需要为字母和符号中的每个字母创建超过26个此类函数。所以,没有使用这种方法。

  2. 我认为这封信的大小是5x5。我们需要点阵打印机做的事情。它打印字符串中每个字母的第1行点,然后打印下一行的第二行点,依此类推。我们打印的字母不是点,而是需要相同的符号。例如,如果我们打印H,那么点就会是&#39; H&#39;

  3. 那么,如何在最少的代码行和更少的复杂性中做到这一点? 我决定为行创建bitflags。考虑到连续有5个点,可能有32种组合。喜欢 - 10000,11000,11100等 在实现这一点时,我开始知道我们不需要那么多来用字母表定义字母。像这样的东西 -

    const unsigned char EOne = 0x1F; // 000 11111 const unsigned char BOne = 0x1E; // 000 11110

  4. 我给bitFlags提供了直观的名字,以便知道它们在信中的位置。 以下是有关bitflags的好消息 - http://www.learncpp.com/cpp-tutorial/3-8a-bit-flags-and-bit-masks/

    1. 下一步是为字母表中的每个字母创建设计。喜欢 -

      const unsigned char A[5] = {AOne, ATwo, EOne, AFiv, AFiv}; const unsigned char B[5] = {BOne, AFiv, BOne, AFiv, BOne}; const unsigned char J[5] = {~EThr, ~BOne, ~BOne, AFiv, ~AFiv};

    2. 因此,这形成了字母A,B,C ...... Z的设计。

      1. 在下一步中,可以在字母表中的字母及其设计之间创建地图。

      2. 当用户输入要打印的字符串时,在5次迭代的for循环中,您可以在其设计中取第0个字母:第0个位标志,第1个字母:其设计中的第1个位标志。第n个字母:第1个位标志在它的设计中。 然后,第0个字母:第1个位标志,第1个字母:第1个位标志,第n个字母:第1个位标志..直到你打印所有5行。

      3. 如何处理bitflag?我使用了std :: bitset并测试了每一位,以便打印或留空格。 lineBits是特定字母设计行的位标记。

        的std ::位集&LT 8是氢;位(lineBits);

        // Since we have only 5x5 letter, we start with leftmost bit (4th) to rightmost (0th)
        for(int bitpos = 4; bitpos >= 0; bitpos--)
        {
            if(bits.test(bitpos))
            {
                cout << letter;
                outFile << letter; // In file.
            }
            else
            {
                cout << " ";
                outFile << " "; // In file.
            }
        }
        
      4. 这样,通过减少代码行,我可以打印任何字符串。因为,我使用地图,很容易打印出来的字母符号。

        FFFFF  RRRR   EEEEE  EEEEE  ZZZZZ  Y   Y  
        F      R   R  E      E          Z   Y Y   
        FFF    RRRR   EEE    EEE      Z      Y    
        F      R R    E      E      Z        Y    
        F      R  RR  EEEEE  EEEEE  ZZZZZ    Y   
        

        花一点时间设计所有字母。让我知道如何改进此代码。