• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            qiezi的學(xué)習(xí)園地

            AS/C/C++/D/Java/JS/Python/Ruby

              C++博客 :: 首頁(yè) :: 新隨筆 ::  ::  :: 管理 ::

            矩陣就不用再解釋了,寫成泛型主要是為了幾個(gè)方便:
            1、方便在棧上分配空間。由于維度在編譯期已知,所以可以做到在棧上分配空間。當(dāng)然如果這個(gè)對(duì)象是new出來(lái)的,自然是在堆上分配,這里說的是在棧上分配這個(gè)對(duì)象時(shí),矩陣元素所占用的空間也在棧上分配。
            2、方便在編譯期檢查非法的矩陣運(yùn)算。C++模板的強(qiáng)大推導(dǎo)能力可以在編譯期推導(dǎo)出結(jié)果矩陣的維度。
            3、泛型類在方法內(nèi)聯(lián)上具有優(yōu)勢(shì)。

            這個(gè)矩陣類為了能夠直接從數(shù)組賦值,使用了一個(gè)ArrayPorxy類(可參考《Imperfect C++》)。

            代碼如下:

            template? < class ?T,? int ?D1,? int ?D2 = 1 >
            class ?ArrayProxy
            {
            ????T
            * ?data;
            public :
            ????ArrayProxy(T?(
            & value)[D1][D2])
            ????????:?data(
            & value[ 0 ][ 0 ])
            ????{
            ????}

            ????ArrayProxy(T?(
            & value)[D1 * D2])
            ????????:?data(value)
            ????{
            ????}

            ????T
            * ?getData()? const
            ????{
            ????????
            return ?data;
            ????}
            };

            這個(gè)只是簡(jiǎn)單的實(shí)現(xiàn)。

            因?yàn)槲一旧喜皇褂眠@個(gè)矩陣類,所以只完成幾個(gè)簡(jiǎn)單功能:
            1、從數(shù)組賦值:
            int a[][3] = {{1,2,3}, {4,5,6}};
            Matrix<int, 2, 3> m1(a);

            int a[] = {1,2,3, 4,5,6};
            Matrix<int, 2, 3> m1(a);
            Matrix<int, 3, 2> m2(a);
            Matrix<int, 6, 1> m3(a);
            Matrix<int, 1, 6> m4(a);

            2、矩陣乘法:
            Matrix<int, 2, 3> m1;
            Matrix<int, 2, 4> m2;
            // m1 * m2? <== 編譯錯(cuò)誤,維度不匹配
            Matrix<int, 3, 5> m3;
            Matrix<int, 2, 5> m4 = m1 * m3; // <== 合法
            // m3 * m1; // <== 編譯錯(cuò)誤,維度不匹配

            源碼如下:

            template?<class?T,?int?R,?int?C>
            class?Matrix
            {
            ????T?matrix[R][C];

            public:
            ????
            //?Big?three
            ????Matrix(void)
            ????{
            ????????memset(matrix,?
            0,?sizeof(matrix));
            ????}

            ????Matrix(
            const?Matrix&?rhs)
            ????{
            ????????memcpy(matrix,?rhs.matrix,?
            sizeof(matrix));
            ????}

            ????Matrix
            &?operator?=(const?Matrix&?rhs)
            ????{
            ????????memcpy(matrix,?rhs.matrix,?
            sizeof(matrix));
            ????????
            return?*this;
            ????}

            public:
            ????Matrix(
            const?ArrayProxy<T,R,C>&?arr)
            ????{
            ????????memcpy(matrix,?arr.getData(),?
            sizeof(matrix));
            ????}

            ????
            ~Matrix(void)
            ????{
            ????}

            public:
            ????T?
            get(int?r,?int?c)?const
            ????{
            ????????assert(c?
            <?C?&&?c?>=?0?&&?r?<?R?&&?r?>=?0);
            ????????
            return?matrix[r][c];
            ????}

            ????
            void?set(int?r,?int?c,?T?v)
            ????{
            ????????assert(c?
            <?C?&&?c?>=?0?&&?r?<?R?&&?r?>=?0);
            ????????matrix[r][c]?
            =?v;
            ????}

            ????
            int?getCols?()?const
            ????{
            ????????
            return?C;
            ????}

            ????
            int?getRows?()?const
            ????{
            ????????
            return?R;
            ????}

            ????
            bool?operator?==?(const?Matrix&?rhs)?const
            ????{
            ????????
            return?memcmp(matrix,?rhs.matrix,?sizeof(matrix))?==?0;
            ????}

            ????
            bool?operator?!=?(const?Matrix&?rhs)?const
            ????{
            ????????
            return?!(*this?==?rhs);
            ????}
            };

            template?
            <class?T,?int?R,?int?C,?int?C1>
            Matrix
            <T,R,C1>?operator*?(const?Matrix<T,R,C>&?lhs,?const?Matrix<T,C,C1>&?rhs)
            {
            ????Matrix
            <T,R,C1>?result;
            ????
            for?(int?r=0;?r<R;?++r)
            ????{
            ????????
            for?(int?c=0;?c<C1;?++c)
            ????????{
            ????????????
            int?value?=?0;
            ????????????
            for?(int?i=0;?i<C;?++i)
            ????????????{
            ????????????????value?
            +=?lhs.get(r,i)?*?rhs.get(i,c);
            ????????????}
            ????????????result.
            set(r,c,value);
            ????????}
            ????}
            ????
            return?result;
            }

            測(cè)試代碼:

            int?main()
            {
            ????{
            ????????
            //?測(cè)試初始化
            ????????Matrix<int,?3,?4>?m1;
            ????????Matrix
            <int,?3,?4>?m2(m1);
            ????????Matrix
            <int,?3,?4>?m3?=?m1;
            ????????Matrix
            <int,?3,?4>?m4;
            ????????m4?
            =?m1;

            ????????
            for?(int?i=0;?i<3;?i++)
            ????????????
            for?(int?j=0;?j<4;?j++)
            ????????????{
            ????????????????assert?(m1.
            get(i,?j)?==?0);
            ????????????????assert?(m2.
            get(i,?j)?==?0);
            ????????????????assert?(m3.
            get(i,?j)?==?0);
            ????????????????assert?(m4.
            get(i,?j)?==?0);
            ????????????}

            ????????
            int?a[]?=?{1,2,3,4,?5,6,7,8,?9,10,11,12};
            ????????Matrix
            <int,?3,?4>?m5(a);

            ????????
            int?b[3][4]?=?{?{1,2,3,4},
            ????????????????????????{
            5,6,7,8},
            ????????????????????????{
            9,10,11,12}};

            ????????Matrix
            <int,?3,?4>?m6(b);

            ????????Matrix
            <int,?3,?4>?m7(m5);
            ????????Matrix
            <int,?3,?4>?m8?=?m5;
            ????????Matrix
            <int,?3,?4>?m9;
            ????????m9?
            =?m5;

            ????????
            for?(int?i=0;?i<3;?i++)
            ????????????
            for?(int?j=0;?j<4;?j++)
            ????????????{
            ????????????????assert?(m5.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m6.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m7.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m8.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m9.
            get(i,?j)?==?i*4+j+1);
            ????????????}

            ????????
            //?維數(shù)不匹配,編譯錯(cuò)誤
            ????????
            //?Matrix<int,?4,?5>?m10?=?m9;
            ????????int?c[][2]?=?{{1,2},?{2,3}};
            ????????
            //?數(shù)組大小不匹配,編譯錯(cuò)誤
            ????????
            //Matrix<int,?3,?4>?m10(c);
            ????????int?d[]?=?{1,2};
            ????????
            //?數(shù)組大小不匹配,編譯錯(cuò)誤
            ????????
            //Matrix<int,?3,?4>?m11(d);

            ????????
            //?乘法維數(shù)不合適,無(wú)法相乘
            ????????
            //m1?*?m2;

            ????????Matrix
            <int,4,3>?m12;
            ????????
            //?匹配,可以相乘
            ????????Matrix<int,?3,?3>?m13?=?m1?*?m12;

            ????????Matrix
            <int,?8,?3>?m14;
            ????????
            //?無(wú)法相乘
            ????????
            //Matrix<int,?3,?3>?m15?=?m1?*?m14;
            ????????
            //?可以相乘
            ????????Matrix<int,?8,?4>?m15?=?m14?*?m1;
            ????}

            ????{
            ????????
            //?檢查點(diǎn)乘
            ????????int?a[2][5]?=?{{1,2,3,4,5},?{6,7,8,9,10}};
            ????????Matrix
            <int,?2,?5>?m1(a);

            ????????
            int?b[5][3]?=?{{1,2,3},?{4,5,6},?{7,8,9},?{10,11,12},?{13,14,15}};
            ????????Matrix
            <int,?5,?3>?m2(b);

            ????????
            int?c[2][3]?=?{{135,150,165},?{310,350,390}};
            ????????Matrix
            <int,?2,?3>?m3(c);

            ????????Matrix
            <int,?2,?3>?m4?=?m1?*?m2;
            ????????assert(m4?
            ==?m3);

            ????????cout?
            <<?m4.get(0,0)?<<?endl;
            ????}

            ????
            return?0;
            }

            補(bǔ)充:
            1、加法、減法只需要2個(gè)矩陣維度相同即可。
            template?<class?T,?class?R,?class?C>
            Matrix
            <T,R,C>?operator+?(const?Matrix<T,R,C>&?lhs,?const?Matrix<T,R,C>&?rhs)
            {
            ???
            //?
            }

            2、由于1x1的矩陣可以看成一個(gè)標(biāo)量,矩陣與標(biāo)量運(yùn)算結(jié)果維數(shù)與原矩陣相同,可以重載來(lái)實(shí)現(xiàn)。
            template?<class?T,?class?R,?class?C>
            Matrix
            <T,R,C>?operator*?(const?Matrix<T,R,C>&?lhs,?const?Matrix<T,1,1>&?rhs)
            {
            ????
            //?
            }

            3、由于類型泛化,可能某些合理的運(yùn)算無(wú)法進(jìn)行,比如float型矩陣,與一個(gè)int型標(biāo)量運(yùn)算等。這些最好是借助類型萃取等手段,推導(dǎo)出運(yùn)算以后的類型。(c++0x中包含自動(dòng)獲取運(yùn)算結(jié)果類型的關(guān)鍵字typeof,等幾年就可以用了:)。GCC編譯器中已有實(shí)現(xiàn),不過似乎有BUG)。

            4、其它。泛型實(shí)現(xiàn)可能會(huì)有一些考慮不周的地方,強(qiáng)類型有強(qiáng)類型的好處,不過必須要有完整的泛型算法支撐,否則難以使用。也可以把泛型矩陣類從一個(gè)普通矩陣類派生,這樣更容易寫出通用算法,不過在實(shí)現(xiàn)上可能要借助于運(yùn)行期多態(tài),對(duì)于矩陣類來(lái)說并不合適。

            5、其它。。前面說C++的模板相當(dāng)強(qiáng)大,D語(yǔ)言模板到目前為止似乎已經(jīng)完全實(shí)現(xiàn)了C++模板的功能,還增加了一些比如字符串值參模板等特性,比C++模板功能更多。在代碼編寫上,由于可以編寫靜態(tài)判斷語(yǔ)句(編譯期)以及靜態(tài)斷言,編寫模板比C++更容易。有時(shí)間可以試試用它寫個(gè)矩陣類,純粹是興趣,這些東西真的很難用到,現(xiàn)成的庫(kù)也挺多。

            6、其它。。。c++0x要提供“template typedef”,也就是可以這樣定義:
            template <int R, int C> typedef Matrix<int, R, C> MatrixInt;? // 定義類型,維度不定
            template <class T> typedef Matrix<T, 4, 4> Matrix4x4; // 定義維度,類型不定
            由此可以出定義行向量、列向量、標(biāo)量等,當(dāng)然實(shí)際使用起來(lái)可能沒那么舒服了。
            posted on 2006-04-13 13:52 qiezi 閱讀(870) 評(píng)論(1)  編輯 收藏 引用 所屬分類: C++
            久久99热只有频精品8| 国产精品美女久久久久久2018| 国产亚洲美女精品久久久久狼| 久久99精品国产麻豆婷婷| 色综合久久久久综合体桃花网| 久久涩综合| 久久国产成人午夜AV影院| 久久久久亚洲国产| 欧美久久久久久午夜精品| 久久国产精品99久久久久久老狼| 99久久精品免费看国产一区二区三区 | 亚洲精品无码专区久久同性男| 国产一久久香蕉国产线看观看| 久久中文字幕无码专区| 91精品国产乱码久久久久久| 久久精品国产亚洲AV嫖农村妇女 | 无码专区久久综合久中文字幕| 久久国产精品久久国产精品| 热99RE久久精品这里都是精品免费 | 一个色综合久久| 99久久亚洲综合精品成人| 日韩欧美亚洲综合久久影院d3| 久久精品视频免费| 色欲久久久天天天综合网| 国产成人无码久久久精品一| 久久国产亚洲精品| 日韩欧美亚洲综合久久影院Ds| 久久久青草青青亚洲国产免观| 婷婷五月深深久久精品| 亚洲欧美一区二区三区久久| 精品国产一区二区三区久久蜜臀| 狠狠色丁香久久婷婷综合五月 | 熟妇人妻久久中文字幕| 久久久久久伊人高潮影院| 无码日韩人妻精品久久蜜桃| 久久久久这里只有精品| 精品久久久久久无码中文字幕 | 国内精品久久久久久麻豆| 色综合久久中文色婷婷| 99精品国产在热久久| 久久久久亚洲AV无码网站|