一种有效的袜子配对算法
前提条件
堆里必须至少有一只袜子桌子必须足够大,以容纳N/2袜子(最坏情况),其中N是总数袜子。
算法
Try:
挑选第一只袜子把它放在桌子上选择下一只袜子,然后看看它(可能会把“不再有袜子”扔到袜子堆里)现在扫描桌子上的袜子(如果桌子上没有袜子,则抛出异常)有匹配的吗?a) 是=>从桌子上取下匹配的袜子b) no=>将袜子放在桌子上(可能会抛出“桌子不够大”异常)
除了:
桌子不够大:小心地将所有未配对的袜子混合在一起,然后继续操作//此操作将导致一个新的堆和一个空表桌子上没有袜子:扔(最后一只不受欢迎的袜子)堆里没有袜子:出口洗衣房
最后:
如果袜子堆里还有袜子:转到3
已知问题
如果或周围没有表,算法将进入无限循环桌子上没有足够的地方容纳至少一只袜子。
可能的改进
根据要分拣的袜子数量,吞吐量可能是通过整理桌子上的袜子来增加空间
为了使其工作,需要一个具有唯一每双袜子的价值。这样的属性很容易根据袜子的视觉财产合成。
按所述属性对桌上的袜子进行排序。让我们调用该属性“颜色”。将袜子排成一排,并将深色袜子放在右侧(即push_back()),左侧(即。.push_front())
对于大量的袜子,尤其是以前看不见的袜子,属性合成可能需要很长时间,因此吞吐量将明显下降。但是,这些属性可以保存在内存中并重用。
需要进行一些研究来评估这种可能性的效率改善出现以下问题:
上述袜子的最佳搭配数量是多少改善对于给定数量的袜子,之前需要多少次迭代吞吐量增加?a) 用于最后一次迭代b) 对于所有迭代
符合MCVE指南的PoC:
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
using namespace std;
struct pileOfsocks {
pileOfsocks(int pairCount = 42) :
elemCount(pairCount<<1) {
srand(time(NULL));
socks.resize(elemCount);
vector<int> used_colors;
vector<int> used_indices;
auto getOne = [](vector<int>& v, int c) {
int r;
do {
r = rand() % c;
} while (find(v.begin(), v.end(), r) != v.end());
v.push_back(r);
return r;
};
for (auto i = 0; i < pairCount; i++) {
auto sock_color = getOne(used_colors, INT_MAX);
socks[getOne(used_indices, elemCount)] = sock_color;
socks[getOne(used_indices, elemCount)] = sock_color;
}
}
void show(const string& prompt) {
cout << prompt << ":" << endl;
for (auto i = 0; i < socks.size(); i++){
cout << socks[i] << " ";
}
cout << endl;
}
void pair() {
for (auto i = 0; i < socks.size(); i++) {
std::vector<int>::iterator it = find(unpaired_socks.begin(), unpaired_socks.end(), socks[i]);
if (it != unpaired_socks.end()) {
unpaired_socks.erase(it);
paired_socks.push_back(socks[i]);
paired_socks.push_back(socks[i]);
}
else
unpaired_socks.push_back(socks[i]);
}
socks = paired_socks;
paired_socks.clear();
}
private:
int elemCount;
vector<int> socks;
vector<int> unpaired_socks;
vector<int> paired_socks;
};
int main() {
pileOfsocks socks;
socks.show("unpaired socks");
socks.pair();
socks.show("paired socks");
system("pause");
return 0;
}