예제 #1
0
 ResultType vector_comprehension(const std::vector<T>& in_vec, Function func) {
     ResultType result;
     result.reserve(in_vec.size());
     for (auto& elem : in_vec) {
         result.push_back(func(elem));
     }
     return result;
 }
std::vector<std::vector<int>> GetCombinationsIterative(const std::vector<int>& input)
{
	typedef std::vector<std::vector<int>> ResultType;
	typedef std::vector<int> InputType;
	typedef std::vector<std::tuple<int, InputType>> ProblemType;
	typedef std::map<int, ProblemType> ProblemListType;
	typedef std::queue<InputType> LevelResultsType;

	ResultType result;
	
	ProblemListType problemTree;

	int currentLevel = input.size();
	int startLevel = currentLevel;
	problemTree[currentLevel] = ProblemType
	{ 
		std::tuple<int, InputType> {0, input}
	};
	InputType temp = input;
	int nodeNr = 1;
	while (currentLevel > 2)
	{
		problemTree[currentLevel - 1] = ProblemType{};
		const auto& nodes = problemTree[currentLevel];
		for (const auto& node : nodes)
		{
			temp = std::get<1>(node);
			for (const auto& element : temp)
			{
				std::vector<int> diffSet = temp;
				diffSet.erase(std::find(diffSet.begin(), diffSet.end(), element));
				problemTree[currentLevel - 1].push_back(std::make_tuple(element, diffSet));
			}
		}
		currentLevel = currentLevel - 1;
	}

	LevelResultsType resultsCurrentLevel;
	LevelResultsType resultsPreviousLevel;
	
	while (currentLevel < startLevel)
	{
		resultsCurrentLevel = {};
		const auto& nodes = problemTree[currentLevel];
		int partitionSize = currentLevel == 2 ? 2 : resultsPreviousLevel.size() / nodes.size();
		for (const auto& node : nodes)
		{
			temp = std::get<1>(node);
			if (temp.size() == 2)
			{
				resultsPreviousLevel.push({ temp[0], temp[1] });
				resultsPreviousLevel.push({ temp[1], temp[0] });
			}
			for (int i = 0; i < partitionSize ; ++i)
			{
				auto& previousLevelResult = resultsPreviousLevel.front();
				previousLevelResult.insert(previousLevelResult.begin(), std::get<0>(node));
				resultsCurrentLevel.push(resultsPreviousLevel.front());
				resultsPreviousLevel.pop();
			}
		}
		resultsPreviousLevel = resultsCurrentLevel;
		++currentLevel;
	}

	while (!resultsCurrentLevel.empty())
	{
		result.push_back(resultsCurrentLevel.front());
		resultsCurrentLevel.pop();
	}

	return result;
}