问题是找到一种方法来达到与以下代码中已达到的结果相同的结果,但是要使用自定义数量的线程,使用临界区和信号量,以便并行化以下代码
我试图并行化代码的递归部分,但是我没有提出任何合理的解决方案
这里的代码可以以某种方式并行化,信号量可以用来并行化代码,但尚不清楚可以并行运行哪些部分
已经在运行的解决方案:
C ++程序找出所有的组合 加上给定数字的正数
#include <iostream>
using namespace std;
// arr - array to store the combination
// index - next location in array
// num - given number
// reducedNum - reduced number
void findCombinationsUtil(int arr[], int index,
int num, int reducedNum)
{
// Base condition
if (reducedNum < 0)
return;
// If combination is found, print it
if (reducedNum == 0)
{
for (int i = 0; i < index; i++)
cout << arr[i] << " ";
cout << endl;
return;
}
// Find the previous number stored in arr[]
// It helps in maintaining increasing order
int prev = (index == 0)? 1 : arr[index-1];
// note loop starts from previous number
// i.e. at array location index - 1
for (int k = prev; k <= num ; k++)
{
// next element of array is k
arr[index] = k;
// call recursively with reduced number
findCombinationsUtil(arr, index + 1, num,
reducedNum - k);
}
}
查找所有组合的功能 加上给定数字的正数。 它使用findCombinationsUtil()
void findCombinations(int n)
{
// array to store the combinations
// It can contain max n elements
int arr[n];
//find all combinations
findCombinationsUtil(arr, 0, n, n);
}
驱动程序代码
int main()
{
int n = 5;
findCombinations(n);
return 0;
}
来源:https://www.geeksforgeeks.org/find-all-combinations-that-adds-upto-given-number-2/
答案 0 :(得分:1)
我将引用另一个答案中的一句话:
我将采取建议路线。在尝试使用线程提高程序速度之前,首先要在单线程情况下提高程序速度。
在您的特定问题中,我认为以某种方式并行化该函数非常困难。例如,您可以让每个线程在原始数组的子数组中找到数字的组合,但是不同子数组中的组合又如何呢?显然,并行化此问题是有限制的,因为每个数字都依赖于每个其他数字。 您可以在进行并行计算之前预先对总和进行缓存,但是如果您希望数字构成组合,将无济于事。
有关更多信息,请参见这些链接。
https://www.codeproject.com/Articles/1247260/Cplusplus-Simple-Permutation-and-Combination-Paral
答案 1 :(得分:0)
好的,有一个合理的解决方案,每个固定数量的和使用一个线程,即5个数字的和是1个线程,4个数字的和是另一个线程,而3个数字的和是另一个线程。 。这样我们就可以使用逻辑核心来处理计算了!
在当前情况下,我不是专业人士(我不假装不是专业人士),这不是完美的解决方案,但它解决了使用并行线程的既定任务,并且有效:
#include "stdafx.h"
#include <fstream>
#include <string>
#include <iostream>
#include <vector>
#include <Windows.h>
#include <chrono>
#include <queue>
typedef int ReverseIterator;
//#define SHOW_RESULTS
CRITICAL_SECTION cs;
HANDLE sem;
HANDLE* threads;
//using namespace std;
std::ifstream g_inputStream;
std::ofstream g_outputStream;
int g_threadCount;
int g_countOfCombinations = 0;
int g_targetNumber = 0;
std::string g_millisecondsSpentOutputStr;
namespace Set {
class ContainerSet {
public:
bool _empty;
int _size;
int* _collection;
int _lastIndex;
ContainerSet* next;
ContainerSet()
{
_lastIndex = 0;
_size = 0;
_collection = nullptr;
_empty = true;
}
ContainerSet(const ContainerSet& source)
{
Initialize(source);
}
void Initialize(const ContainerSet& source)
{
_lastIndex = 0;
_size = source._size;
_collection = new int[_size];
for (int i = 0; i < _size; i++) {
_collection[i] = source[i];
}
_empty = false;
}
ContainerSet(int size)
{
_lastIndex = 0;
_collection = new int[size];
_size = size;
_empty = false;
}
~ContainerSet()
{
if (_empty == true)
return;
else {
if (_collection) {
delete _collection;
_collection = nullptr;
_empty = true;
}
}
}
int operator[] (int i) const {
if (_collection == nullptr)
return -1;
return _collection[i];
}
int& operator[](int i) {
if (_collection == nullptr)
return _collection[0];
return _collection[i];
}
bool operator<(const ContainerSet& left)
{
return left._collection < this->_collection;
}
int size() { if (this == nullptr) return 0; return _size; }
bool Equal(ContainerSet* set) {
if (_collection == nullptr || _size < 0 )
return false;
for (int i = 0; i < set->size(); i++)
{
if (set->_collection[i] != this->_collection[i])
return false;
}
if(set->size() == this->size())
return true;
return false;
}
int* rbegin() { return &_collection[_size - 1]; }
int* rend() { return &_collection[0]; }
int* begin() { return &_collection[0]; }
int* end() { return &_collection[_size - 1]; }
};
class DynamicListOfSets {
public:
bool _empty;
ContainerSet* _last;
ContainerSet* _first;
DynamicListOfSets()
{
Initialize(this);
}
static void Initialize(DynamicListOfSets* list) {
list->_first = nullptr;
list->_last = nullptr;
}
ContainerSet* back() {
return _last;
}
bool HasEqualMember(ContainerSet* member)
{
if (_first == nullptr)
{
return false;
}
ContainerSet* current = _first;
do {
//do stuff
if (current->Equal(member))
return true;
current = current->next;
} while (current->next != nullptr);
return false;
}
ContainerSet* front()
{
return _first;
}
void push_back(ContainerSet* set)
{
if (set == nullptr)
return;
set->next = nullptr;
if (_last == nullptr) {
_first = set; _last = set;
} else {
_last->next = set;
_last = set;
}
_empty = false;
}
void clear() {
ContainerSet* current = _first;
if (current == nullptr) {
_empty = true;
return;
}
ContainerSet* next = current->next;
do {
//extract next from current
next = current->next;
//delete current
delete current;
//move next
current = next;
//if next exist
} while (next != nullptr);
_empty = true;
}
void pop_front() {
if (_first != nullptr)
{
auto next = _first->next;
delete _first;
if (next != nullptr)
_first = next;
}
}
~DynamicListOfSets()
{
_empty = true;
}
};
class ListOfSets {
public:
//data fields
ContainerSet** _collection;
int _size;
int _pointer;
ContainerSet* operator[] (int i) const {
if (_collection == nullptr)
return nullptr;
return _collection[i];
}
//constructors
ListOfSets()
{
_size = 0;
_collection = nullptr;
_pointer = -1;
}
ListOfSets(int size)
{
Initialize(this, size);
}
static void Initialize(ListOfSets* list, int size)
{
list->_size = size;
list->_collection = new ContainerSet*[size];
for (int i = 0; i < size; i++)
{
list->_collection[i] = new ContainerSet(size);
}
list->_pointer = -1;
}
//methods
int size()
{
return _size;
}
void push_back(ContainerSet* list)
{
if (!IsFull())
{
if (list == nullptr)
{
//TODO: check and correct here
throw 0;
return;
}
_pointer++;
_collection[_pointer] = list;
}
}
ContainerSet* next(int index)
{
if ( (index+1) >= _size)
return nullptr;
return _collection[index + 1];
}
ContainerSet* front()
{
if(_collection != nullptr)
return _collection[0];
return nullptr;
}
ContainerSet* pop_back()
{
if (!HasValues())
return nullptr;
else {
if(_pointer-1 >= 0)
return _collection[_pointer--];
return false;
}
}
ContainerSet* pop_front()
{
if (!HasValues())
return nullptr;
else {
if (_pointer >= 0)
return _collection[0];
return false;
}
}
bool IsFull()
{
return (_pointer + 1) >= _size;
}
bool HasValues()
{
if (_collection == nullptr || _size <= 0)
return false;
return true;
}
ContainerSet* rbegin()
{
if (_collection == nullptr || _collection[_size - 1] == nullptr)
return nullptr;
return _collection[_size - 1];
}
ContainerSet* rend()
{
if (_collection == nullptr || _collection[0] == nullptr)
return nullptr;
return _collection[0];
}
ContainerSet* begin()
{
if (_collection == nullptr || _collection[0] == nullptr)
return nullptr;
return _collection[0];
}
ContainerSet* end()
{
if (_collection == nullptr || _collection[_size - 1] == nullptr)
return nullptr;
return _collection[_size - 1];
}
void clear()
{
if (_collection == nullptr)
return;
if (_collection[0]) {
for (int cSI = 0; cSI < _size; cSI++)
{
if (_collection[cSI] != nullptr)
{
delete _collection[cSI];
_collection[cSI] = new Set::ContainerSet();
}
}
}
ListOfSets();
}
~ListOfSets() {
clear();
}
};
}
typedef Set::ContainerSet SolutionIntContainer;
namespace SimpleTimer {
class SimpleTimer
{
public:
SimpleTimer::SimpleTimer()
{
start = std::chrono::high_resolution_clock::now();
stopped = false;
}
std::string SimpleTimer::Stop()
{
end = std::chrono::high_resolution_clock::now();
duration = end - start;
float result = duration.count();
std::string strResult;
strResult.append("Time spent: ");
strResult.append(std::to_string(result));
strResult.append("seconds");
strResult.append("\n");
return strResult;
}
std::string SimpleTimer::StopMilliseconds()
{
stopped = true;
end = std::chrono::high_resolution_clock::now();
duration = end - start;
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
std::string strResult;
strResult.append(std::to_string(millis));
return strResult;
}
SimpleTimer::~SimpleTimer()
{
if (stopped)
return;
end = std::chrono::high_resolution_clock::now();
duration = end - start;
float result = duration.count();
std::cout << "Time spent: " << result << " seconds" << std::endl;
}
private:
std::chrono::time_point<std::chrono::steady_clock> start, end;
std::chrono::duration<float> duration;
bool stopped;
};
}
namespace NewSolution {
bool Equal(SolutionIntContainer* left, SolutionIntContainer* right) {
for (int i = 0; i < (left->size() - 1); i++) {
if ((*left)[i] != (*right)[i])
return false;
}
return true;
}
int Difference(int sum) {
return g_targetNumber - sum;
}
int Difference(SolutionIntContainer& targetList) {
int sum = 0;
for (auto it = targetList.rbegin(); it >= targetList.rend(); it--) {
sum += (*it);
}
return Difference(sum);
}
class CombinationStorage {
private:
Set::DynamicListOfSets descendants;
public:
// constructors
CombinationStorage(int size) {
Set::DynamicListOfSets::Initialize(&descendants);
}
// methods
void DeleteDescendants() {
//descendants.clear();
}
bool FindDescendant(SolutionIntContainer* sIC) {
auto it = descendants.front();
while (it != nullptr) {
if (Equal(it, sIC))
return true;
it = it->next;
}
return false;
}
void AddDescendant(SolutionIntContainer* combinationNode) {
if (combinationNode != nullptr)
descendants.push_back(new SolutionIntContainer(*combinationNode));
}
SolutionIntContainer* GetNextDescendant() {
return descendants.front();
}
void DeleteFrontDescendant() {
descendants.pop_front();
}
}; // class CombinationComparator
class ListHandler {
private:
CombinationStorage combinationStorage;
SolutionIntContainer sourceList;
public:
// public fields:
static Set::ListOfSets startingCombinations;
//constructor:
ListHandler(SolutionIntContainer* s, int size) : combinationStorage(size)
{
sourceList.Initialize(*s);
//InitializeCombinations();
}
//methods:
void DeleteInnerDescendants()
{
combinationStorage.DeleteDescendants();
}
void NewDescendantFound(SolutionIntContainer* combination)
{
g_countOfCombinations++;
combinationStorage.AddDescendant(combination);
}
void CombinationFound(SolutionIntContainer* combination) {
g_countOfCombinations++;
}
bool RightIsGreaterOrEqual(int left, int right) {
if (right >= left)
return true;
return false;
}
int IncludingIndexDifference(int sum, int reductionOffset)
{
return ((g_targetNumber - reductionOffset) - sum);
}
//Tested OK 10:47 PM 5/23/2019
bool CheckOrder(SolutionIntContainer& list, int maxIndex)
{
// TODO: optimize
int leftI = 0, rightI = 1;
int sum = list[leftI];
for (; rightI <= maxIndex; leftI++, rightI++) {
if (!RightIsGreaterOrEqual(list[leftI], list[rightI]))
return 1;
sum += list[rightI];
}
int reductionOffset = 0;
for (int i = (rightI + 1); i < list.size(); i++)
{
reductionOffset += list[i];
}
return IncludingIndexDifference(sum, reductionOffset);
}
static void ShowList(SolutionIntContainer& list, std::string* additionalContents = nullptr, bool reversed = false)
{
#ifdef SHOW_RESULTS
if (reversed) {
for (auto i = list.rbegin(); i >= list.rend(); i--)
{
std::cout << (*i) << " ";
}
}
else {
for (auto i = list.begin();
i <= list.end();
i++) {
std::cout << (*i) << " ";
}
}
if (additionalContents != nullptr) {
std::cout << " \t " << *additionalContents << " \t ";
}
std::cout << std::endl;
#endif
}
static void ShowCombination(SolutionIntContainer& container, std::string* additionalContents = nullptr, bool reversed = false) {
#ifdef SHOW_RESULTS
std::cout << g_countOfCombinations << ") \t";
ShowList(container, additionalContents, reversed);
#endif
}
void Inc(SolutionIntContainer& list, int index, int count = 1) {
if (index < 0 || index >= list.size())
return;
list[index] = list[index] + count;
}
void Dec(SolutionIntContainer& list, int index) {
if (index < 0 || index >= list.size())
return;
list[index] = list[index] - 1;
}
void TryDecAndInc(SolutionIntContainer& newList, SolutionIntContainer& oldList, int reductionIndex, int increasingIndex)
{
newList.Initialize(oldList);
Dec(newList, reductionIndex);
Inc(newList, increasingIndex);
}
SolutionIntContainer& TryDecAndInc(SolutionIntContainer& const newList, int reductionIndex, int increasingIndex)
{
Dec(newList, reductionIndex);
Inc(newList, increasingIndex);
return newList;
}
bool RebuildDownstairs(SolutionIntContainer& list, int rightI, int leftI = -1)
{
if (leftI == -1)
leftI = rightI - 1;
SolutionIntContainer newTryList;
TryDecAndInc(newTryList, list, rightI, leftI);
if (CheckOrder(newTryList, rightI) > 0)
return false;
if (!combinationStorage.FindDescendant(&newTryList)) {
NewDescendantFound(&newTryList);
list[rightI] = list[rightI] - 1;
list[leftI] = list[leftI] + 1;
#ifdef SHOW_RESULTS
std::string indexesStr = std::string("rightIndex = ") + std::to_string(rightI) +
+" ; " + std::string("leftIndex = ") + std::to_string(leftI) + std::string(";");
ShowCombination(list
, &indexesStr
);
#endif //SHOW_RESULTS
return true;
}
return false;
}
bool GlidePossible(SolutionIntContainer& sIC)
{
int first = sIC[0];
int last = sIC[sIC.size() - 1];
int offset = 1;
if (last > (first + offset))
{
return true;
}
return false;
}
int startingLeftLeftIndex;
bool glode = false;
int lastRight = 1;
int lastLeft = 1;
bool Exists(SolutionIntContainer& list, int minR, int maxL) {
if (minR == lastRight && maxL == lastLeft)
return true;
return false;
}
void TryGhostGlideALine(SolutionIntContainer& list, int rightIndex, int leftLeftI,
int& depthOverall, int currentDepth)
{
SolutionIntContainer newTryList(list);
while (depthOverall == currentDepth) //(true)
{
if (leftLeftI < 0) {
leftLeftI = startingLeftLeftIndex;
}
if (!GlidePossible(newTryList))
return;
TryDecAndInc(newTryList, rightIndex, leftLeftI);
if (CheckOrder(newTryList, rightIndex) <= 0) {
if (
!combinationStorage.FindDescendant(&newTryList)
) {
NewDescendantFound(&newTryList);
//if(newTryList[rightIndex] < lastRight)
lastRight = newTryList[rightIndex];
//if (newTryList[leftLeftI] > lastLeft)
lastLeft = newTryList[leftLeftI];
ShowCombination(newTryList);
}
TryGhostGlideALine(newTryList, rightIndex, leftLeftI, ++depthOverall, ++currentDepth);
// Repeat recursively
TryGhostGlideALine(newTryList, rightIndex, (leftLeftI - 1),
(depthOverall = currentDepth),
/*++*/currentDepth
);
} else {
return;
}
leftLeftI--;
}
}
void ChangeValue(SolutionIntContainer& container, int index, int value) {
container[index] = value;
}
bool CanDecRightAndIncLeft(SolutionIntContainer& list, int rightI, int leftI) {
return CheckOrder(TryDecAndInc(list, rightI, leftI), rightI) <= 0;
}
bool FindNext(SolutionIntContainer& list, int rightI)
{
bool result = true;
// working with previous
// Find the left Element
// Check if left element is to the left of right
int leftI = (rightI - 1);
// exit if can't shift
// (exit if left doesn't exist)
if (leftI < 0)
return false;
// TODO: exit condition
if (!RebuildDownstairs(list, rightI))
return false;
// a third element we are currently working on
// it is to the third position to the left
// and more if needed
int leftLeftI = (leftI - 1);
if (leftLeftI >= 0)
{
startingLeftLeftIndex = leftLeftI;
int depth = 0;
lastRight = list[rightI];
lastLeft = 1;
//TODO: check if works
combinationStorage.DeleteDescendants();
TryGhostGlideALine(list, rightI, leftLeftI, depth, depth//, 0
);
}
// Ghost Glide OK, continue
return result;
}
// Rebuild saving existing right element
bool RebuildCombination(SolutionIntContainer& list,
ReverseIterator rightIndex)
{
if (rightIndex <= 0)
return false;
// strictly more than 0 because we move towards left border
// and check for the previous (right - 1) element
int orderDisplacement = CheckOrder(list, rightIndex);
if (orderDisplacement < 0)
Inc(list, rightIndex);
if (orderDisplacement > 0)
return false;
int leftI = (rightIndex - 1);
// Find the changed
while (FindNext(list, rightIndex)) {
}
return true;
}
static void InitializeCombinations( int count )
{
Set::ListOfSets::Initialize(&startingCombinations, count-1);
for (int i = count; i > 1; i--)
{
SolutionIntContainer* newList = new SolutionIntContainer(i);
for (int k = 0; k < i; k++) {
(*newList)[k] = 1;
}
startingCombinations.push_back(newList);
}
}
void FindAllSumsFixedLength()
{
ShowList(sourceList);
int rightIndex = /*firstRun ?*/ sourceList.size() - 1 /*: iterator - 1*/;
int left = (rightIndex - 1);
int difference = g_targetNumber;
while ((difference = NewSolution::Difference(sourceList)) > 0) {
sourceList[rightIndex]++;
}
NewDescendantFound(&sourceList);
ShowCombination(sourceList);
while (
RebuildCombination(sourceList, rightIndex)
)
{
--rightIndex;
}
}
static SolutionIntContainer Next()
{
EnterCriticalSection(&::cs);
if (startingCombinations.size() == 0)
return SolutionIntContainer(0);
SolutionIntContainer* sourceList = startingCombinations.pop_front();
LeaveCriticalSection(&::cs);
return *sourceList;
}
static void WriteLineThreadBlocking(const char* line, int length = 0)
{
EnterCriticalSection(&::cs);
std::cout << line << std::endl;
LeaveCriticalSection(&::cs);
}
static DWORD WINAPI FindAllSumsFixedLengthMT(LPVOID pListHandler)
{
ListHandler* pLH = (ListHandler*)pListHandler;
DWORD dwWaitResult;
BOOL bContinue = TRUE;
// Try to enter the semaphore gate.
dwWaitResult = WaitForSingleObject(
sem, // handle to semaphore
INFINITE); // zero-second time-out interval
int rightIndex = 0;
int left = 0;
int difference = g_targetNumber;
switch (dwWaitResult)
{
// The semaphore object was signaled.
case WAIT_OBJECT_0:
//// TODO: Perform task
bContinue = FALSE;
rightIndex = /*firstRun ?*/ pLH->sourceList.size() - 1 /*: iterator - 1*/;
left = (rightIndex - 1);
//TODO: test Added 9/24/2019
if (rightIndex < 0)
return FALSE;
while ((difference = NewSolution::Difference(pLH->sourceList)) > 0) {
pLH->sourceList[rightIndex]++;
}
pLH->NewDescendantFound(&pLH->sourceList);
ShowCombination(pLH->sourceList);
while (
pLH->RebuildCombination(pLH->sourceList, rightIndex)
)
{
--rightIndex;
}
pLH->combinationStorage.DeleteDescendants();
// Release the semaphore when task is finished
if (!ReleaseSemaphore(
sem, // handle to semaphore
1, // increase count by one
NULL)) // not interested in previous count
{
//printf("ReleaseSemaphore error: %d\n", GetLastError());
}
break;
// The semaphore was nonsignaled, so a time-out occurred.
case WAIT_TIMEOUT:
//printf("Thread %d: wait timed out\n", GetCurrentThreadId());
break;
}
delete pLH;
return TRUE;
}
}; // CombinationListHandler
} // New Solution //
Set::ListOfSets NewSolution::ListHandler::startingCombinations;
bool InitializeStreams()
{
try {
g_inputStream = std::ifstream();
g_inputStream.open("input.txt");
g_outputStream = std::ofstream();
g_outputStream.open("output.txt", std::ios::trunc);
return true;
} catch (...) {
return false;
}
}
void Output()
{
g_outputStream << g_threadCount;
g_outputStream << std::endl;
g_outputStream << g_targetNumber;
g_outputStream << std::endl;
g_outputStream << g_millisecondsSpentOutputStr;
g_outputStream << std::endl;
}
void CloseStreams()
{
g_inputStream.close();
g_outputStream.close();
}
bool InitializeInputData() {
try {
g_threadCount = -1;
g_targetNumber = -1;
// Read count of threads from the file
std::string tempLine;
std::getline(g_inputStream, tempLine);
g_threadCount = std::stoi(tempLine);
// Read the target number from the file
std::getline(g_inputStream, tempLine);
g_targetNumber = std::stoi(tempLine);;
if (g_threadCount == -1 || g_targetNumber == -1) {
return false;
}
} catch (...) {
return false;
}
return true;
}
void RunNewSolutionMultiThreaded() {
SimpleTimer::SimpleTimer simpleTimer = SimpleTimer::SimpleTimer();
g_countOfCombinations = 0;
NewSolution::ListHandler::InitializeCombinations(g_targetNumber);
for (int i = 0
; i < NewSolution::ListHandler::startingCombinations.size();
i++)
{
NewSolution::ListHandler::ShowList(*NewSolution::ListHandler::startingCombinations[i]);
}
sem = CreateSemaphore(
NULL, // default security attributes
1, // initial count
g_threadCount, // maximum count
NULL); // unnamed semaphore
if (sem == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
}
// Initialize the critical section one time only.
if (!InitializeCriticalSectionAndSpinCount(&cs,
0x00000400))
return;
// Create worker threads
DWORD ThreadID;
threads = new HANDLE[NewSolution::ListHandler::startingCombinations.size()];
for (int i = 0; i < NewSolution::ListHandler::startingCombinations.size(); i++)
{
threads[i] = 0;
}
int lastThreadID = -1; int i = 0;
for (int i = 0;
i < NewSolution::ListHandler::startingCombinations.size();
i++
)
{
auto it = NewSolution::ListHandler::startingCombinations._collection[i];
if (NewSolution::Difference(*it) == 0) {
g_countOfCombinations++;
//NewSolution::ListHandler::ShowCombination(*it);
continue;
}
++lastThreadID;
NewSolution::ListHandler* listHandler = new NewSolution::ListHandler(it, it->size());
listHandler->DeleteInnerDescendants();
//listHandler->FindAllSumsFixedLength();
threads[lastThreadID] = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE)NewSolution::ListHandler::FindAllSumsFixedLengthMT,
(LPVOID)listHandler, // thread function argument
0, // default creation flags
&ThreadID); // receive thread identifier
if (threads[lastThreadID] == NULL)
{
printf("CreateThread error: %d\n", GetLastError());
return;
}
}
// Wait for all threads to terminate
WaitForMultipleObjects(lastThreadID + 1, threads, TRUE, INFINITE);
// Close thread and semaphore handles
for (int i = 0; i <= lastThreadID; i++)
CloseHandle(threads[i]);
delete[] threads;
CloseHandle(sem);
// Release resources used by the critical section object.
DeleteCriticalSection(&cs);
//NewSolution::ListHandler::startingCombinations.~ListOfSets();
std::cout << "Count of combinations " << g_countOfCombinations /*+ g_targetNumber-1*/ << std::endl;
std::cout << "*** New Solution Execution Completed ***" << std::endl;
// Counting time spent
g_millisecondsSpentOutputStr = simpleTimer.StopMilliseconds();
std::cout << "Time spent: " << g_millisecondsSpentOutputStr << std::endl;
}
int main()
{
g_countOfCombinations = 0;
if (
!InitializeStreams()
) {
std::cout << "File \"input.txt\" doesn't exist. Quiting..." << std::endl;
system("pause");
return 1;
}
if ( !InitializeInputData() ) {
std::cout << "Input file is currupted... Quiting..." << std::endl;
system("pause");
return 1;
}
RunNewSolutionMultiThreaded();
Output();
CloseStreams();
system("pause");
return 0;
}