C++ 如何映射/索引向量(整数)以快速访问和比较c++;

C++ 如何映射/索引向量(整数)以快速访问和比较c++;,c++,performance,vector,C++,Performance,Vector,我有一个int向量,它增长得非常大(有意的) 从视觉上看,这将(a,b,c,d)与(e,f,g,h)进行比较,因为b==e&&c==f&&d==g *我试着用int向量作为键映射。。。但这太慢了(我想我做错了) 下面是一个独立的.cpp,如果有人需要它或者它更有意义: 参数为零(默认为12)或两个大于3的空格分隔整数(预先警告此算法的复杂性为O(n!)) #包括 #包括 #包括 #包括 #包括 #包括 使用名称空间std; //最小时钟大小3 矢量硬币(整数时钟大小,矢量硬币) { int to

我有一个int向量,它增长得非常大(有意的)

从视觉上看,这将(a,b,c,d)与(e,f,g,h)进行比较,因为b==e&&c==f&&d==g


*我试着用int向量作为键映射。。。但这太慢了(我想我做错了)

下面是一个独立的.cpp,如果有人需要它或者它更有意义:

参数为零(默认为12)或两个大于3的空格分隔整数(预先警告此算法的复杂性为O(n!))

#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
//最小时钟大小3
矢量硬币(整数时钟大小,矢量硬币)
{
int totalCheckedCombos=0;
向量群;
向量硬币集=_硬币;
排序(coinSet.begin(),coinSet.end());
擦除(唯一的(coinSet.begin()、coinSet.end()、coinSet.end());
地图硬币计数;
对于(int i=0;i你可以选择树状结构

树的工作原理是这样的:每一条边都用一枚硬币标记。树的叶子存储引用向量的所有成员,这些成员的尾巴与从根到叶子的轨迹相匹配

在预处理中,通过遍历所有向量创建该树,并尝试遍历该树,如果不可能,则扩展该树

在主例程中,您只需尝试遍历向量的每个头部的树


两者的结果复杂度都是O(N*M*deg),deg是该树中节点的最大出度,小于不同硬币的数量,N是向量的数量,M是尾部/头部的大小。假设M和deg不随输入量的增加而增加,则为O(N).

如果您投票关闭plz,请花一点时间解释一下我如何能让这个问题变得更好。我花了大量的精力寻找后,找不到这个问题的答案(可能是因为我的无知)。我是这个社区的新手,显然还不擅长发布问题。“我尝试用int的向量作为密钥……但那是超慢的(我假设我做错了)”假设没有。重复使用小于大的、类似的<代码>向量<代码> >以使用<代码> map <代码>将是残酷的。考虑在计算和存储哈希的类中封装内部<代码>矢量< /代码>。(
HashedVector
)然后看看一个
std::unordered_map
是否满足您的性能要求。这样,您只需计算散列冲突的相等性。选择好散列算法,这应该很少见。tyvm,我将尝试一下!您能将您的代码示例转换为完整的可编译和可运行示例吗?如果您关心性能,请使用运算符[]而不是向量的at,对at()进行边界检查,这可能会破坏编译器可以进行的许多潜在优化。另外,请确保您是使用带gcc/clang的优化-O2或-O3进行编译的。
vector<vector<int>> coinGroups;
//bool match = equal(coinGroups.at(i).begin()+1, coinGroups.at(i).end(), coinGroups.at(ii).begin());
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>
#include <sstream>

using namespace std;

//min clock size 3
vector<vector<int>> placeCoins(int _clockSize, vector<int> _coins)
{
    int totalCheckedCombos = 0;
    vector<vector<int>> coinGroups;
    vector<int> coinSet = _coins;
    sort(coinSet.begin(), coinSet.end());
    coinSet.erase(unique(coinSet.begin(), coinSet.end()), coinSet.end());

    map<int, int> coinCounts;
    for (int i = 0; i < coinSet.size(); i++)
    {
        coinCounts[coinSet.at(i)] = count(_coins.begin(), _coins.end(), coinSet.at(i));
    }

    cout << "pairs" << endl;
    //generate fair pairs of coins
    for (int i = 0; i < coinSet.size(); i++)
    {
        for (int ii = 0; ii < coinSet.size(); ii++)
        {
            if ((coinSet.at(i) + coinSet.at(ii)) % _clockSize != 0)
            {
                if (i == ii)
                {
                    if (coinCounts[coinSet.at(i)] > 1)
                    {
                        coinGroups.push_back({ coinSet.at(i),coinSet.at(ii) });
                    }
                }
                else
                {
                    coinGroups.push_back({ coinSet.at(i),coinSet.at(ii) });
                }
            }
        }
    }

    cout << "combine" << endl;
    //iteratively combine groups of coins
    for (int comboSize = 3; comboSize < _clockSize; comboSize++)
    {
        totalCheckedCombos += coinGroups.size();
        vector<vector<int>> nextSizeCombos;
        for (int i = 0; i < coinGroups.size(); i++)
        {
            for (int ii = 0; ii < coinGroups.size(); ii++)
            {
                //check combo to match

                //cleaner but slower due to inability to breakout early on compare check
                //bool match = equal(coinGroups.at(i).begin()+1, coinGroups.at(i).end(), coinGroups.at(ii).begin());

                bool match = true;
                for (int a = 0; a < comboSize - 2; a++)
                {
                    if (coinGroups.at(i).at(a+1) != coinGroups.at(ii).at(a))
                    {
                        match = false;
                        break;
                    }
                }

                //check sum
                if (match)
                {
                    vector<int> tempCombo = coinGroups.at(i);
                    int newVal = coinGroups.at(ii).at(coinGroups.at(ii).size()-1);
                    tempCombo.push_back(newVal);
                    if (coinCounts[newVal] >= count(tempCombo.begin(), tempCombo.end(), newVal))
                    {
                        if (accumulate(tempCombo.begin(), tempCombo.end(), 0) % _clockSize != 0)
                        {
                            nextSizeCombos.push_back(tempCombo);
                        }
                    }
                }
            }
        }

        if (nextSizeCombos.size() == 0)
        {
            //finished, no next size combos found
            break;
        }
        else
        {
            cout << nextSizeCombos.size() << endl;
            coinGroups = nextSizeCombos;
        }
    }
    cout << "total combos checked: " << totalCheckedCombos << endl;
    return coinGroups;
}

//arguments are _clockSize _coinCount
//The goal of this algorithm is to create combos of stepSizeTokens (coins) which fill a loop of register locations (clock)
int main(int argc, char *argv[]) {
    int clockSize = 12;
    int coinCount = 12;

    if (argc >= 2)
    {
        std::istringstream iss(argv[1]);
        if (!(iss >> clockSize))
        {
            cout << "argument 1 invalid" << endl;
            cout << "press enter to end program" << endl;
            cin.get();
            return 0;
        }
        std::istringstream iss2(argv[2]);
        if (!(iss2 >> coinCount))
        {
            cout << "argument 2 invalid" << endl;
            cout << "press enter to end program" << endl;
            cin.get();
            return 0;
        }
    }

    if (clockSize < 3) { clockSize = 3; }

    vector<int> coins = {};
    cout << "coin list:" << endl;
    for (int i = 0; i < coinCount; i++)
    {
        int tempCoin = rand() % (clockSize - 1) + 1;
        cout << tempCoin << " , ";
        coins.push_back(tempCoin);
    }
    cout << endl;


    vector<vector<int>> resultOrders = placeCoins(clockSize, coins);

    cout << "max combo size: " << resultOrders.at(0).size() << endl;
    cout << "number of max combos found: " << resultOrders.size() << endl;

    cout << "press enter to end program" << endl;
    cin.get();
}