2011-01-05 37 views
3

我目前正在將Python中的算法轉換爲C++。C++中簡明的列表/向量

這條線EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]] 現在

vector<vector<char>> exch_symbols; 

    vector<char> vector_1il; 
    vector_1il.push_back('1'); 
    vector_1il.push_back('i'); 
    vector_1il.push_back('l'); 

    vector<char> vector_5s; 
    vector_5s.push_back('5'); 
    vector_5s.push_back('s'); 

    vector<char> vector_8b; 
    vector_8b.push_back('8'); 
    vector_8b.push_back('b'); 

    vector<char> vector_mn; 
    vector_mn.push_back('m'); 
    vector_mn.push_back('n'); 

    exch_symbols.push_back(vector_1il); 
    exch_symbols.push_back(vector_5s); 
    exch_symbols.push_back(vector_8b); 
    exch_symbols.push_back(vector_mn); 

我不喜歡有用於在2-d向量中的每個內的可變的中間命名的變量是。我並不熟悉C++中的多維數據結構。有沒有更好的辦法?

發生了什麼事以後是這樣的:

multimap<char, char> exch_symbol_map; 

/*# Insert all possibilities 
    for symbol_set in EXCH_SYMBOL_SETS: 
     for symbol in symbol_set: 
      for symbol2 in symbol_set: 
       if symbol != symbol2: 
        exch_symbol_map[symbol].add(symbol2)*/ 
void insert_all_exch_pairs(const vector<vector<char>>& exch_symbols) { 
    for (vector<vector<char>>::const_iterator symsets_it = exch_symbols.begin(); 
     symsets_it != exch_symbols.end(); ++symsets_it) { 
      for (vector<char>::const_iterator sym1_it = symsets_it->begin(); 
       sym1_it != symsets_it->end(); ++sym1_it) { 
        for (vector<char>::const_iterator sym2_it = symsets_it->begin(); 
         sym2_it != symsets_it->end(); ++sym2_it) { 
          if (sym1_it != sym2_it) { 
           exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it)); 
          } 
        } 
      } 
    } 
} 

所以這個算法應該在這樣或那樣的工作,表示在這裏。目標是可以稍後輕鬆更改EXCH_SYMBOL_SETS以包含新組char s或向現有組添加新字母。謝謝!

+1

當您將較高級別的語言轉換爲較低級別時,會出現許多醜陋,不雅,非慣用的非最佳代碼。你已經習慣了。 – delnan 2011-01-05 11:07:48

+0

你是完全正確的。但問題是,我怎樣處理python中的多維向量?我甚至不知道如何翻譯'L = [A,[B] ,[[C],D]]]'到C++。 ..根本! ...另外,我不需要堅持這個算法。如果可能,我想寫得更好。事情是,即使我已經用C++而不是Python開始了這個項目,我想我也不會想出更好的東西。 – 2011-01-05 11:12:22

回答

2

我會重構,而不是vector<char>,使用std::string內部,即

vector<string> exch_symbols; 
exch_symbols.push_back("1il"); 
exch_symbols.push_back("s5"); 
exch_symbols.push_back("b8"); 
exch_symbols.push_back("mn"); 

然後更改您的插入方法:

void insert_all_exch_pairs(const vector<string>& exch_symbols) 
{ 
    for (vector<string>::const_iterator symsets_it = exch_symbols.begin(); symsets_it != exch_symbols.end(); ++symsets_it) 
    { 
    for (string::const_iterator sym1_it = symsets_it->begin(); sym1_it != symsets_it->end(); ++sym1_it) 
    { 
     for (string::const_iterator sym2_it = symsets_it->begin(); sym2_it != symsets_it->end(); ++sym2_it) 
     { 
     if (sym1_it != sym2_it) 
      exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it)); 
     } 
    } 
    } 
} 
+1

每一個答案都很好,但這肯定是一條可行的路。我不知道'string'有一個迭代器。 (我的講師花了他的C++講授,告訴我們如何編寫自己的字符串類,可惜他應該閱讀Bjarne關於如何教C++的書...) – 2011-01-05 11:32:04

+0

btw。你意識到上述算法不一定會創建所有的映射嗎?例如,i1l,只有兩對產生i1,1i,li(原因是另一對被跳過,因爲它是相同的密鑰) - 這是你想要的嗎?如果沒有,我會建議將'map'改爲'multimap' – Nim 2011-01-05 12:16:39

+0

我不明白這是真的。首先,我已經使用了一個multimap(參見第二個代碼片段的第一行),並且該算法遍歷整個正方形{i,1,l} x {i,1,l},並且如果它是xx則只會丟棄一對。它應該生成{i1,il,1i,1l,l1,li}並且工作正常。 – 2011-01-05 17:33:19

1

您可以通過擺脫中間值

vector<vector<char> > exch_symbols(4, vector<char>()); //>> is not valid in C++98 btw. 
//exch_symbols[0].reserve(3) 
exch_symbols[0].push_back('i'); 
etc. 

你也可以使用boost.assign或類似的東西
EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]]就變成 vector<vector<char>> exch_symbols(list_of(vector<char>(list_of('i')('1')('l')))(vector<char>(list_of('s')('5'))(list_of('m')('n')))(未測試的縮短,且從未嵌套向量使用它,但它應該是這樣的)

1

您的代碼:

vector<char> vector_1il; 
    vector_1il.push_back('1'); 
    vector_1il.push_back('i'); 
    vector_1il.push_back('l'); 

簡潔的代碼:

char values[] = "1il"; 
vector<char> vector_1il(&values[0], &values[3]); 

你是不是罰款?


如果你想使用std::stringNim的建議,那麼你可以使用連這個:

//Concise form of what Nim suggested! 
std::string s[] = {"1il", "5s", "8b", "mn"}; 
vector<std::string> exch_symbols(&s[0], &s[4]); 

休息,你可以按照Nim's post。 :-)

+0

感謝您的編輯!這真的很好 – 2011-01-05 12:39:40

1

對於你真正的問題...

我怎麼能翻譯L = [A,[B], [C],d]]]到C++在...所有!

沒有直接翻譯 - 您已經從相同類型的存儲值切換到變量類型的存儲值。 Python允許這樣做,因爲它是一種動態類型語言,並不是因爲它具有更好的數組語法。

有許多方法可以複製C++中的行爲(例如,一個boost :: any或boost :: variant類型的向量,或者一個支持這個類的用戶定義的容器類),但它永遠不會像在Python中那麼容易。

1

C++ 0x中的指令
vector<string> EXCH_SYMBOL_SETS={"i1l", "s5", "b8", "mn"} ;
編譯和工作正常。可悲的是顯然類似的聲明
vector<vector<char>> EXCH_SYMBOL_SETS={{'i','1','l'},{'s','5'}, {'b','8'}, {'m','n'}};
不:-(工作。

這在G ++ 4.5.0實施以後,你應該添加-std=c++0x選項。我​​覺得這個功能是不是在微軟尚未avaliable c(VC10),我不知道其他編譯器的狀態如何。