12

次のコードを使用して、長方形の面積と周囲長を計算したいと思います。

    rect a;
    a = ( -----
          !   !
          -----a );
std::cout << a.area() << std::endl;
std::cout << a.perimeter() << std::endl;

この目的のために、私は次のクラスを作成しました。

class rect
{
public:
    rect():w(0), h(2) {}
    rect& operator - () { w += 0.5f; return *this; }
    rect& operator - (rect&) { w += 0.5f; return *this; }
    rect& operator -- (int a) { w += a; return *this; }
    rect& operator -- () { w += 1; return *this; }
    rect& operator ! () { h += 0.5f; return *this; }
    void clear() { w = 0; h = 2; }
    int area() { return w * h; }
    int perimeter() { return 2 * w + 2 * h; }
    int width() { return w; }
    int height() { return h; }
private:
    float w;
    float h;
};

いくつかの使用例を次に示します。

#include <iostream>

int main()
{
    rect a;

    a = ( -----
          !   !
          -----a );

    std::cout << a.area() << std::endl;
    std::cout << a.perimeter() << std::endl;
    std::cout << a.width()  << std::endl;
    std::cout << a.height() << std::endl;

    std::cout << std::endl;

    a.clear();

    a = ( ----------
          !        !
          !        !
          !        !
          !        !
          ---------a );

    std::cout << a.area() << std::endl;
    std::cout << a.perimeter() << std::endl;
    std::cout << a.width()  << std::endl;
    std::cout << a.height() << std::endl;

    return 0;
}

これが私の質問です:

  1. 浮動小数点演算を使用せずに実行できますか? (実際、それは整数グリッドです)
  2. 3Dケースで一般化できますか?すなわち:

    cuboid b;
    b = (  ---------
          /        /!
         ! -------! !
         !        ! !
         !        ! !
         !        !/
         ---------b );
    
    std::cout << b.volume() << std::endl;
    
4

2 に答える 2

8

接頭辞「/」演算子がないため、「/」演算子を「+」に変更する必要がありました。+でもうまくいきます。ああ、それはintを使用しています。あなたが提供したケースで一度だけテストしましたが、私が知る限り、それはうまくいくはずです.

class cuboid
{
        int w,h,l;
public:
        cuboid () : w(2), h(3), l(6) {}
        cuboid& operator - () { w += 1; return *this; }
        cuboid& operator - (cuboid&) { w += 1; return *this; }
        cuboid& operator -- (int) { w += 2; return *this; }
        cuboid& operator -- () { w += 2; return *this; }
        cuboid& operator ! () { h += 1; return *this; }
        cuboid& operator + () { l += 1; return *this; }
        cuboid& operator + (cuboid&) { l += 1; return *this; }
        cuboid& operator ++ () { l += 2; return *this; }
        cuboid& operator ++ (int) { l += 2; return *this; }

        void clear () { w = 2; h = 3; l = 6; }
        int width () const { return w / 3; }
        int height () const { return h / 3; }
        int length () const { return l / 3; }
        int volume () const { return width() * height () * length (); }
        int surface_area() const { return width() * height () * 2 +
                                          width() * length () * 2 +
                                          length() * height () * 2; }
};

実際に見てください。 http://ideone.com/vDqEm

編集: 2 つの + が隣り合ってはならないため、++ 演算子は必要ありません。おっと。

于 2012-07-27T15:30:32.857 に答える
2

並べ替え。文字セットの高さと幅が等しいか、単位がピクセルではなく単なる文字であると仮定する限り、浮動小数点演算を使用せずに配列を四角形として検証し、それに関する計算を行うのは簡単です。したがって、長方形の実際の形状は文字セットに基づいて変化しますが、論理的には 3 文字 x 2 文字のままです。

しかし、3D ケースでいくつかの問題が発生します。まず、配列を使用したグリッドベースのレイアウトを使用して実際に表現することはできません。アスキーアートをもう一度見てください。正面の角度は?サイドエッジを観察できるため、ゼロではありません。それが 90 度の角度である場合、側面が見える場合は、前面も同様に角度を付ける必要があります。したがって、あなたの表現方法は、3D 立方体を表現するタスクに対応していません。

ただし、代替手段があります。3D アスキー アートは、話している 3D ターゲットの抽象化である場合があります。スラッシュ/バックスラッシュ文字は、文字 '-' および '!' と同じように、正確に 1 単位の長さになりました。文字。その前提で、3D バージョンも非常に些細なことですが、表示するとかなり奇妙に見えます。

つまり、これらの立方体を見てください。これらはユークリッド フレンドリーではありません。

  ---
 / /!
--- !
! !/
---

   ----
  /  /|
 /  / |
----  |
|  | /
|  |/
----

とにかく、これらが 2D または 3D 形状を表すアスキー アート文字列であると仮定すると、次のようになります。

//Skipping the validation step, assuming well formed ascii rectangles.
int height2D(char* rect, int size)
{
    int ret=0;
    int i=0;
    while(i++ < size) 
        if(rect[i] == '\n')
            ret++;
    return ret;
}

int width2D(char* rect, int size)
{
    int ret=0;
    while(rect[ret] == '-' && ret < size)
        ret++;
    return ret;
}

int area2D(char* rect, int size)
{
    //return height2D(rect, size) * width2D(rect, size);
    //ppfffft!
    return size;
}

int perimiter2D(char* rect, int size)
{
    return 2 * height2D(rect, size) + 2 * width2D(rect, size);
}



//Skipping the validation step, assuming well formed ascii cuboids
int height3D(char* rect, int size)
{
    int ret=0;
    int i=0;
    int depth;

    while(i++ < size) 
        if(rect[i] == '\n')
            ret++;
    depth = depth3D(rect, size);
    return ret - depth + 2;
}

int width3D(char* rect, int size)
{
    int ret=0;
    int i=0;
    while(rect[i] != '-' && ret < size)
        i++;
    while(rect[i++] == '-' && ret < size)
        ret++;

    return ret;
}

int depth3D(char* rect, int size)
{
    int ret=0;
    while(rect[ret] == ' ' && ret < size)
        ret++;
    return ret+1;
}

int volume3D(char* rect, int size)
{
    return height3D(rect, size) * width3D(rect, size) * depth3D(rect, size);
}

int area3D(char* rect, int size)
{
    return 2 * heigh3D(rect, size) * width3D(rect, size) + 
           2 * heigh3D(rect, sise) * depth3D(rect, size) + 
           2 * width3D(rect, size) * depth3D(rect, size);
}

テストも検証もされていません。これをコンパイルすることさえしませんでした。地獄、それを疑似コードと呼びましょう。

于 2012-07-23T16:00:42.357 に答える