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)
と思う人のために、これはアルゴリズムに関する学校の割り当てですが、私が求めていないよ:。問題が興味を持っている人のためにここで見つけることができ、より高いレベルに等しい量のものそれを助けるために私は既にJavaで完成しているからです。問題は、私のアルゴリズムがC++になると大変なことに思えることです。
Javaでは約0.6秒、C++では「同じ」コードが2秒以上(制限時間を超過)です。
誰かが私にこの理由についてのポインタを教えてください。私はC++がこれらのタイプの問題に関してJavaよりもおそらく早いという印象を受けました。
あなたは再帰的なアプローチを使用しているのはなぜ?単に準備した( 'resize()' d) 'std :: vector'にできるだけ多くのデータを読み込もうとしないのはなぜですか? –
これは[codereview](http://codereview.stackexchange.com/)サイトに適しています。つまり、C++の初心者であるため、コンパイラの最適化を有効にしましたか? Javaはデフォルトでそれらを取得しましたが、C++では通常はそれらを有効にする必要があります。 –
「データ」はどれくらい大きいですか?あなたはどこにでもそれをコピーしています – vu1p3n0x