2009-11-16 81 views
0

我的模型最好使用一些C++ as in Java?:載體向量*變量*長度int

v int [30] [i] [N_i];

結構,它是整數的元組30層的載體,其中

v [0]是僞,
V [1]是純整數(其中N_0)
V [2]是對INT(N_1對)
...
v [29]。將INT的29元組(其中N_29)的

這是不vector<vector<int>>像在「通用矢量-的-vectors- in-c「

顯然,外部固定dim = 30是沒有問題的,內部的是由自擴展的STL向量類處理的。

有沒有辦法讓中間維度固定,但不是恆定的?

+0

你試圖實際使用STL std :: vector類,還是這個本地C++數組? – qid 2009-11-16 14:48:07

+0

不知道我理解這個問題。你的意思是像'組<假人,矢量,矢量,...,矢量'(或者,如果N_0,...,N29是常數:'組<空,INT [N_0],INT [2 ] [N_1],...,int [29] [N_29]')? – 2009-11-16 19:30:13

+0

這個問題的標題顯示「...和Java一樣」:也許解釋你如何用Java來做這件事可以幫助我們理解。 – 2009-11-16 19:32:23

回答

0

做你想做的事情的最好方法是在矢量訪問器中編寫包裝函數。包裝現有行爲的最好方法是編寫一個新的類,該類使用你的向量向量來實現。

2

正如我在你的問題的評論中寫的,我不確定要了解你在找什麼(我對「如Java中的」部分很感興趣,順便說一下)。

但是因爲我認爲這很有趣,看看如何使用Boost生成它。 MPL(和Fusion ...和Array),我假設你想有一個靜態定義的結構,它的Ntn元素的大小爲N INT陣列的載體:

#define FUSION_MAX_VECTOR_SIZE 30 

#include <boost/mpl/transform.hpp> 
#include <boost/mpl/vector.hpp> 
#include <boost/mpl/inserter.hpp> 
#include <boost/mpl/range_c.hpp> 
#include <boost/mpl/size_t.hpp> 

#include <boost/fusion/include/mpl.hpp> 
#include <boost/fusion/include/at_c.hpp> 
#include <boost/fusion/include/as_vector.hpp> 

#include <boost/array.hpp> 

#include <vector> 


namespace bf = boost::fusion; 
namespace bmpl = boost::mpl; 

// Type generator used for elements 2..N 
// For those elements, the type of the n'th element is 
// std::vector<boost::array<int, n>> 
template<class SizeT> 
struct VectorOfArray 
{ 
    typedef std::vector<boost::array<int, SizeT::type::value> > type; 
}; 

// The dummy type used for the first element 
struct Dummy{}; 

// The container itself 
template<size_t Size> 
struct StrangeContainer 
{ 

    // Define a fusion::vector (this is, more or less, equivalent to a tuple) 
    // of "Size" elements, where: 
    // - the type of element 0 is Dummy, 
    // - the type of element 1 is vector<int> 
    // - the type of the n'th element is vector<array<int, n>> 
    typedef typename bf::result_of::as_vector< 
     typename bmpl::transform< 
      bmpl::range_c<size_t, 2, Size>, 
      VectorOfArray<bmpl::_1>, 
      bmpl::back_inserter< 
       bmpl::vector<Dummy, std::vector<int> > 
      > 
     >::type 
    >::type ContentsType; 

    // Helper struct to compute the return type of the "At()" member 
    template<size_t I> 
    struct ElemType 
    { 
     typedef typename VectorOfArray<bmpl::size_t<I> >::type type; 
    }; 

    // Specialize "At()"'s return type for element 1 
    template<> 
    struct ElemType<static_cast<size_t>(1)> 
    { 
     typedef std::vector<int> type; 
    }; 

    // Specialize "At()"'s return type for element 0 
    template<> 
    struct ElemType<static_cast<size_t>(0)> 
    { 
     typedef Dummy type; 
    }; 

    // Get the I'th element 
    template<size_t I> 
    typename ElemType<I>::type& 
    At() 
    { 
     return bf::at_c<I>(m_Contents); 
    } 

    // The fusion vector holding the elements 
    ContentsType m_Contents; 
}; 

int main() 
{ 
    StrangeContainer<30> s; 
    Dummy& d = s.At<0>(); 
    s.At<1>().push_back(1); 
    s.At<2>().push_back(boost::array<int, 2>()); 
    s.At<3>().push_back(boost::array<int, 3>()); 
    s.At<29>().push_back(boost::array<int, 29>()); 
    s.At<29>()[0][0] = 1234; 

    return 0; 
} 
+0

+1,非常優雅的解決方案。 – 2009-11-17 09:13:48

0

我是邁克爾(最初的作者)現在有ID La-AIDA

首先,謝謝大家,Boost &融合凡新對我來說。

去Éric: 一個錯字:v [1]應該有N_1條目,v [2] N_2等等。 我想STL類的東西,而不是C數組(缺乏邊界檢查,沒有選擇添加它)。

對愛立克的新評論: 我試過你的解決方案,它立即就可以工作(幾乎可以在刪除虛擬查詢之後)! 謝謝! 但是:我需要這樣的東西

for (i = 1;i < 30;i++) { 
    cout << s.At<i>[0] << endl; 
} 

也就是說,對於在<指數..>應變量(即整點,以能夠運行的索引,而不是治療分別30硬編碼的東西)
但GCC與錯誤抱怨:「I」中不能出現一個常數表達式

關於「在Java中」: AfaIk,Java中的二元矩陣不是一些 int v [10] [10]; 固定尺寸,但類似於 int [] [] v; 其中首先有一個

v = new int[10][]; 

(或類似的語法),然後,這是點:

v[0] = new int[1]; 
... 
v[9] = new a[10]; 

這使得三角矩陣,或當然你喜歡的任何形式。 事實上,一個10乘10的矩陣也需要1加10個新的矩陣。

關於結構本身: 的等效數據結構將是

vector<int> v1; 
vector<pair<int,int>> v2; 
vector<int,int,int> v3; 
... 
vector<int[29]> v29; 

然而其中我們將必須單獨處理各30份。

我想能夠說v[5][3][123] = 99; 設置第3部分在123五元組99個,沒有定義

vector<int> v[30][30]; 

它會做的伎倆,但浪費了巨大的空間,因爲 從未使用過v[1][2..30][0..\infty] or more generally v[i][i+1..30][*]。因此,在我的問題中,我有一個int的列表,其中有三對的三元組...,它們都是可排序的int元組的30個元組,這些元素都可以排序等等,而不會浪費空間。

+0

一個小挑逗:你應該編輯你的問題,而不是張貼「答案」。這種方式更容易找到,它將答案分組爲答案,而不是混合的答案和問題。 – Jonas 2009-12-01 21:07:16

+0

是的;-) 我問「匿名邁克爾」,我的問題不再是我的,可能沒有人可以編輯它(除了網站維護者等)。 – user222408 2009-12-02 08:21:53

+0

At <>的索引必須是常量,因爲At的返回類型是索引的函數。 但是,您可以使用boost :: fusion :: for_each迭代Fusion序列的元素。 – 2009-12-22 20:58:48