2016-05-13 20 views
0

TL; DR:私のコードはJavaでは「高速」ですが、C++では非常に遅いです。どうして?C++の高速化アルゴリズム

#include <iostream> 
#include <vector> 
#include <map> 
#include <algorithm> 


using namespace std; 

int read(string data, int depth, int pos, vector<long>& wantedList) { 
    // 91 = [ 
    if (data.at(pos) == 91) { 
     pos++; 
     // Get first part 
     pos = read(data, depth + 1, pos, wantedList); 
     // Get second part 
     pos = read(data, depth + 1, pos, wantedList); 
    } else { 
     // Get the weight 
     long weight = 0; 
     while (data.length() > pos && isdigit(data.at(pos))) { 
      weight = 10 * weight + data.at(pos++) - 48; 
     } 
     weight *= 2 << depth; 
     wantedList.push_back(weight); 
    } 
    return ++pos; 
} 


int doStuff(string data) { 
    typedef map<long, int> Map; 
    vector<long> wantedList; 
    Map map; 
    read(data, 0, 0, wantedList); 
    for (long i : wantedList) { 
     if (map.find(i) != map.end()) { 
      map[i] = map[i] + 1; 
     } else { 
      map[i] = 1; 
     } 
    } 

    vector<int> list; 
    for (Map::iterator it = map.begin(); it != map.end(); ++it) { 
     list.push_back(it->second); 
    } 
    sort(list.begin(), list.begin() + list.size()); 
    cout << wantedList.size() - list.back() << "\n"; 
    return 0; 

} 

int main() { 
    string data; 
    int i; 
    cin >> i; 
    for (int j = 0; j < i ; ++j) { 
     cin >> data; 
     doStuff(data); 
    } 
    return 0; 
} 

最初のC++プロジェクトを試したところ、Javaのコードを書き直しました。 元のタスクは、何かの上の各レベルが下の2倍の重さを持つと仮定して、入力の「バランスを取る」ために変更する必要のある数字の数を計算することでした。

例:[1,2]両側で等しくなるように1-> 2または2-> 1であり、[8、[4,2]]は「下位レベル」が8になるためには1回の変更(2-> 4)

Problem link

と思う人のために、これはアルゴリズムに関する学校の割り当てですが、私が求めていないよ:。問題が興味を持っている人のためにここで見つけることができ、より高いレベルに等しい量のものそれを助けるために私は既にJavaで完成しているからです。問題は、私のアルゴリズムがC++になると大変なことに思えることです。

Javaでは約0.6秒、C++では「同じ」コードが2秒以上(制限時間を超過)です。

誰かが私にこの理由についてのポインタを教えてください。私はC++がこれらのタイプの問題に関してJavaよりもおそらく早いという印象を受けました。

+0

あなたは再帰的なアプローチを使用しているのはなぜ?単に準備した( 'resize()' d) 'std :: vector 'にできるだけ多くのデータを読み込もうとしないのはなぜですか? –

+2

これは[codereview](http://codereview.stackexchange.com/)サイトに適しています。つまり、C++の初心者であるため、コンパイラの最適化を有効にしましたか? Javaはデフォルトでそれらを取得しましたが、C++では通常はそれらを有効にする必要があります。 –

+3

「データ」はどれくらい大きいですか?あなたはどこにでもそれをコピーしています – vu1p3n0x

答えて

5

コピーの可能性が考えられます。

C++で値で何かを渡すたびに、コピーが作成されます。 doubleintやポインタのような音の場合は問題ありません。

しかし、std::stringのようなオブジェクトの場合、コピーが高価になる可能性があります。あなたがdataを変更しないので、それはconst参照で、それを渡すことは理にかなって:

int read(const string &data, int depth, int pos, vector<long>& wantedList) 
関連する問題