C++ 循环/方法太慢

C++ 循环/方法太慢,c++,c++11,C++,C++11,我目前正在处理来自hackerrank的一个问题,我正在超过我的问题的时间限制。我似乎不明白为什么 输出差异最小的数对。如果有多对,则按升序输出所有对,所有对都在同一行(连续),每对数字之间只有一个空格。如果有一个数字存在于两对中,则将其打印两次(有关解释,请参见示例案例#3) 输入数 包含由空格分隔的所有元素的字符串 样本: 4 5 4 3 2 输出: 2 3 3 4 4 5 我失败的测试用例有100000个输入。我对代码计时,代码中最慢的部分是函数中最近的循环。我最初有一个向量,然后在得

我目前正在处理来自hackerrank的一个问题,我正在超过我的问题的时间限制。我似乎不明白为什么

输出差异最小的数对。如果有多对,则按升序输出所有对,所有对都在同一行(连续),每对数字之间只有一个空格。如果有一个数字存在于两对中,则将其打印两次(有关解释,请参见示例案例#3)

输入数 包含由空格分隔的所有元素的字符串

样本:

4
5 4 3 2
输出:

2 3 3 4 4 5
我失败的测试用例有100000个输入。我对代码计时,代码中最慢的部分是函数
中最近的循环。我最初有一个向量,然后在得到列表后使用std:sort。然后我尝试使用multiset而不是调用std::sort来提高性能。它仍然没有通过测试。关于如何改进
最近的
中的循环或方法
addPair
有什么想法吗

#include <iostream>
#include <set>
#include <utility>
#include <cmath>
#include <string>
#include <algorithm>
#include <ctime>

#define NUMBER 10000
double diffclock(clock_t clock1, clock_t clock2)
{
    double diffticks = clock1 - clock2;
    double diffms = (diffticks) / (CLOCKS_PER_SEC / NUMBER);
    return diffms;
}

class ClosestPair
{
    private:
        long _distance;
        const char UNSET = -1;
        std::multiset<int> _list;
        long getDistance(const int number1, const int number2) const;

    public:
        ClosestPair();
        ~ClosestPair();
        void addPair(const int number1, const int number2);
        const std::multiset<int>& getList() const;
        const std::string toString() const;
        void sort();

};

ClosestPair::ClosestPair()
{
    _distance = UNSET;
}

ClosestPair::~ClosestPair()
{
}

void ClosestPair::addPair(const int number1, const int number2)
{
    long distance = getDistance(number1, number2);

    if(distance < _distance || _distance == UNSET)
    {
        _list.clear();
        _distance = distance;
        //std::pair<int, int> newPair(number1, number2);
        //_list.push_back(newPair);
        _list.insert(number1);
        _list.insert(number2);
    }
    else if(distance == _distance)
    {
        _list.insert(number1);
        _list.insert(number2);
        //std::pair<int, int> newPair(number1, number2);
        //_list.push_back(newPair);
    }
}

inline long ClosestPair::getDistance(const int number1, const int number2) const
{
    return std::abs(number1 - number2);
}

const std::multiset<int>& ClosestPair::getList() const
{
    return _list;
}

const std::string ClosestPair::toString() const
{
    std::string allPairs;

    for(auto iterator = _list.begin(); iterator != _list.end(); iterator++)
    {
        allPairs += std::to_string(*iterator);
        allPairs += " ";
        //allPairs += std::to_string(iterator->second);
        //allPairs += " ";
    }

    if(allPairs.size() > 0)
    {
        allPairs.substr(0, allPairs.size() - 1);
    }

    return allPairs;
}

void ClosestPair::sort()
{
    //std::sort(_list.begin(), _list.end());
}

void closest(int* array, int size)
{
    ClosestPair closestPairs;

    clock_t begin = clock();
    for(int i = 0; i < size; i++)
    {
        for(int j = i + 1; j < size; j++)
        {
            closestPairs.addPair(array[i], array[j]);
        }
    }
    clock_t end = clock();
    std::cout << "AddPair time: " << diffclock(end, begin) << " ms." << std::endl;

    //closestPairs.sort();
    begin = clock();
    std::cout << closestPairs.toString();
    std::cout << "toString time: " << diffclock(end, begin) << " ms." << std::endl;
    end = clock();
}

int main()
{
    int sizeOfList;
    std::string allNumbers;
    std::cin >> sizeOfList >> std::ws;
    std::getline(std::cin, allNumbers);

    size_t position = 0;
    size_t nextPosition = 0;
    int count = 0;
    int array[sizeOfList];

    clock_t begin = clock();
    do
    {
        position = nextPosition;
        nextPosition = allNumbers.find(' ', position + 1);
        if(position > 0)
            position++;
        array[count] = atoi(allNumbers.substr(position, nextPosition - position).c_str());
        count++;
    }
    while(nextPosition != std::string::npos);
    clock_t end = clock();
    std::cout << "Tokenize time: " << diffclock(end, begin) << " ms." << std::endl;

    closest(array, sizeOfList);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义数字10000
双差分时钟(时钟1、时钟2)
{
双diffticks=时钟1-时钟2;
双diffms=(diffticks)/(每秒时钟/数字);
返回diffms;
}
类ClosestPair
{
私人:
长距离;
const char UNSET=-1;
标准::多集列表;
长距离(常数整数1,常数整数2)常数;
公众:
ClosestPair();
~ClosestPair();
void addPair(常数整数编号1,常数整数编号2);
常量std::multiset&getList()常量;
常量std::字符串toString()常量;
无效排序();
};
ClosestPair::ClosestPair()
{
_距离=未设置;
}
ClosestPair::~ClosestPair()
{
}
void ClosestPair::addPair(常数整数编号1,常数整数编号2)
{
长距离=getDistance(数字1,数字2);
如果(距离<| | | | |距离==未设置)
{
_list.clear();
_距离=距离;
//std::配对新配对(number1,number2);
//_列表。推回(新对);
_列表。插入(编号1);
_列表。插入(编号2);
}
else if(距离==\u距离)
{
_列表。插入(编号1);
_列表。插入(编号2);
//std::配对新配对(number1,number2);
//_列表。推回(新对);
}
}
内联长距离闭合空气::getDistance(常数int number1,常数int number2)常数
{
返回标准::abs(编号1-编号2);
}
常量std::multiset&ClosestPair::getList()常量
{
返回列表;
}
常量std::string ClosestPair::toString()常量
{
std::字符串所有对;
for(自动迭代器=_list.begin();迭代器!=_list.end();迭代器++)
{
allPairs+=std::to_字符串(*迭代器);
所有对+=“”;
//allPairs+=std::to_字符串(迭代器->秒);
//所有对+=“”;
}
if(allPairs.size()>0)
{
allPairs.substr(0,allPairs.size()-1);
}
返回所有对;
}
void ClosestPair::sort()
{
//排序(_list.begin(),_list.end());
}
无效最近(整数*数组,整数大小)
{
闭气闭气;
时钟开始=时钟();
对于(int i=0;i//需要[b,e]排序:
模板
std::vector find_close_对(迭代器b,迭代器e){
if(b==e | | std::next(b)==e)返回{};
std::vector retval={0};
自动旧=*std::next(b)-*b;
对于(自动it=std::next(b);std::next(it)!=e;++it){
自动增量=*std::next(it)-*it;
如果(增量<旧){
retval.clear();
old=delta;
}
如果(delta
//要求[b,e]已排序:
模板
std::vector find_close_对(迭代器b,迭代器e){
if(b==e | | std::next(b)==e)返回{};
std::vector retval={0};
自动旧=*std::next(b)-*b;
对于(自动it=std::next(b);std::next(it)!=e;++it){
自动增量=*std::next(it)-*it;
如果(增量<旧){
retval.clear();
old=delta;
}

如果(delta如果我正确理解你的问题,你也可以使用多重映射。映射的键/值是int/pair(int,int)

一次检查排序列表中的两个数字。计算两个数字之间的差异。该差异将成为地图中的一个键值,而这对数字就是您用来计算差异的两个数字

完成后,可以保证最小的差异出现在映射的开头,因为映射使用<对键进行排序。现在,您拥有最小的差异以及导致该差异的数字对的信息

例如:

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

typedef std::multimap<int, std::pair<int, int>> IntMap;
typedef std::vector<int> IntVect;

void getDifferences(const IntVect& intVect, IntMap& theMap)  // assume intVect is     sorted
{
    theMap.clear();
    if (intVect.size() < 2)
        return;

    size_t nItems = intVect.size();
    for (size_t i = 0; i < nItems - 1; ++i)
    {
       int num1 = intVect[i+1];
       int num2 = intVect[i];
       int diff = num1 - num2
       theMap.insert(std::make_pair(diff, std::make_pair(num2, num1)));
    }
}

int main()
{
    int Test[] = { 3, 4, 2, 7, 1, 11 };
    IntVect testV(Test, Test + sizeof(Test) / sizeof(Test[0]));
    std::sort(testV.begin(), testV.end());
    IntMap myMap;
    getDifferences(testV, myMap);
}
#包括
#包括
#包括
typedef std::multimap IntMap;
typedef std::vector IntVect;
void getDifferences(const IntVect&IntVect,IntMap&theMap)//假设IntVect已排序
{
theMap.clear();
if(intVect.size()<2)
返回;
size_t nItems=intVect.size();
对于(尺寸i=0;i

请注意,在构建地图时,不必检查最小值。这有点“安全”,但其他非地图答案可能执行得更快。

如果我正确理解您的问题,您也可以使用多重地图。地图的键/值为int/pair(int,int)

一次浏览已排序的列表中的2个数字。计算两个数字之间的差异。该差异将成为映射中的一个键值,并且这对数字是t
#include <map>
#include <vector>
#include <algorithm>

typedef std::multimap<int, std::pair<int, int>> IntMap;
typedef std::vector<int> IntVect;

void getDifferences(const IntVect& intVect, IntMap& theMap)  // assume intVect is     sorted
{
    theMap.clear();
    if (intVect.size() < 2)
        return;

    size_t nItems = intVect.size();
    for (size_t i = 0; i < nItems - 1; ++i)
    {
       int num1 = intVect[i+1];
       int num2 = intVect[i];
       int diff = num1 - num2
       theMap.insert(std::make_pair(diff, std::make_pair(num2, num1)));
    }
}

int main()
{
    int Test[] = { 3, 4, 2, 7, 1, 11 };
    IntVect testV(Test, Test + sizeof(Test) / sizeof(Test[0]));
    std::sort(testV.begin(), testV.end());
    IntMap myMap;
    getDifferences(testV, myMap);
}