一个整数数组,长度为n,将其分为m份,使各份的和相等,求m.(下)

    之前那篇说另外一种写法的雏形出现在我的脑海中,现在终于都写完并且调试完成了。现在放上来,以免到时候又忘记了写过的东西。

耿马网站建设公司创新互联建站,耿马网站设计制作,有大型网站制作公司丰富经验。已为耿马近千家提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的耿马做网站的公司定做!

    现在又重构了一下那段代码,而且进行了比较多的调试都没问题了应该是比较稳定的这段程序。现在把重构后的代码把原代码覆盖,7月29日更新

    今天面试的时候面试官有看过我这段代码说我这段代码当中含有会让系统宕机的可能,然后我回来之后灰常仔细的看终于都发现了那个可能了,那个erase那个函数那里如果firstElemIter==lastElemIter的时候,第一个if进去了然后后面那个if进去之后firstElemIter就会判断不等于lastElemIter这个时候进行循环减减的操作会导致在第一个元素--的操作然后就会宕机,然后我发现是必然的但是为什么之前的调试没办法调试出来呢?我在微软的vs平台上面调试的,然后拿一个比较小的数组进去测试没想到到了那个第一个元素的时候--操作不会进行然后那个isDeleted()函数也不会调用循环直接退出了好奇怪啊,但是代码明明跟到这里连个报错都没有然后那个lastElemIter还是指向第一个元素,后来我把这段代码改了从新调试发现也没问题,现在就把那个改了的代码放上来还有之前的有问题的代码保留吧因为后面就不知道我之前出问题没发现的地方了。8月12日更新。

#include
#include
#include

using namespace std;

typedef vector intArray_t;

class StrangeInt {
public:
	StrangeInt();
	StrangeInt(int value);
	StrangeInt(const StrangeInt &ref);
	bool isDeleted();
	void setDeleted(bool deleted);
	int getValue();
	int getRefCount();
	void incRefCount();
	void decRefCount();
	bool operator < (const StrangeInt &ref);
private:
	int refCount;
	bool deleted;
	int value;
};

class StrangeIter {
public:
	StrangeIter(list::iterator &iter, list *array, list::iterator &firstElemIter, list::iterator &lastElemIter);
	list::iterator incIter();
	list::iterator decIter();
	list::iterator firstElem();
	list::iterator lastElem();
	void erase();
	void insert(int value);
	bool isFirstElem();
	list::iterator getCurIter();
	void incItsRefCount();
	void decItsRefCount();
	bool isEmpty();
private:
	list::iterator &iter;
	list *array;
	list::iterator lastDelPos;
	bool lastHadDel;
	bool isFirst;
	list::iterator &firstElemIter;
	list::iterator &lastElemIter;
	bool hadDelFirst;
	bool hadDelLast;
};

StrangeInt::StrangeInt(){
}
StrangeInt::StrangeInt(int value) : value(value), refCount(0), deleted(false){
}

StrangeInt::StrangeInt(const StrangeInt& ref) : value(ref.value), refCount(ref.refCount), deleted(ref.deleted) {
}

bool StrangeInt::isDeleted() {
	return deleted;
}

void StrangeInt::setDeleted(bool deleted) {
	this->deleted = deleted;
}

int StrangeInt::getValue() {
	return value;
}

int StrangeInt::getRefCount() {
	return refCount;
}

void StrangeInt::incRefCount() {
	refCount++;
}

void StrangeInt::decRefCount() {
	refCount--;
}

bool StrangeInt::operator < (const StrangeInt &ref) {
	return value < ref.value;
}

StrangeIter::StrangeIter(list::iterator &iter, list *array, list::iterator &firstElemIter, list::iterator &lastElemIter) : iter(iter), array(array), lastHadDel(false), isFirst(false), firstElemIter(firstElemIter), lastElemIter(lastElemIter){
}

list::iterator StrangeIter::incIter() {
	
	if (iter == lastElemIter) {
		iter = array->end();
	}
	else {
		while ((++iter)->isDeleted());
	}
	return iter;
}

list::iterator StrangeIter::decIter() {
	if (!isFirstElem()) {
		while ((--iter)->isDeleted());
	}
	return iter;
}

list::iterator StrangeIter::firstElem() {
	return firstElemIter;
}

list::iterator StrangeIter::lastElem() {
	return lastElemIter;
}

bool StrangeIter::isFirstElem() {
	if (firstElem() == iter)
		return true;
	return false;
}

void StrangeIter::erase() {

	hadDelFirst = false;
	hadDelLast = false;
	if (lastElemIter == firstElemIter) {
		hadDelFirst = true;
		hadDelLast = true;
		firstElemIter = array->end();
		lastElemIter = array->end();
	}
	else if (iter == firstElemIter) {
		hadDelFirst = true;
		while ((++firstElemIter)->isDeleted());
	}
	else if (iter == lastElemIter) {
		hadDelLast = true;
		while ((--lastElemIter)->isDeleted());
	}
	
/*	if (iter == firstElemIter) {
		hadDelFirst = true;
		if (lastElemIter == firstElemIter) {
			firstElemIter = array->end();
		}
		else {
			while ((++firstElemIter)->isDeleted());
		}
	}
	else
		hadDelFirst = false;
	if (iter == lastElemIter) {
		hadDelLast = true;
		if (lastElemIter == firstElemIter) {
			lastElemIter = array->end();
		}
		else {
			while ((--lastElemIter)->isDeleted());
		}
	}
	else
		hadDelLast = false;
*/
	if (iter->getRefCount() > 0) {
		iter->setDeleted(true);
		lastDelPos = iter;
		lastHadDel = false;
		if (hadDelLast)
			iter = array->end();
		else
			while((++iter)->isDeleted());
	}
	else {
		if (iter == array->begin()) {
			isFirst = true;
			array->erase(iter++);
			if (hadDelLast)
				iter = array->end();
			else
				if (iter->isDeleted())
					while((++iter)->isDeleted());
		}
		else {
			array->erase(iter--);
			lastDelPos = iter;
			if (!iter->isDeleted()) {
				iter->incRefCount();
			}
			if (hadDelLast)
				iter = array->end();
			else
				while((++iter)->isDeleted());
		}
		lastHadDel = true;
	}
}

void StrangeIter::insert(int value) {
	if (lastHadDel) {
		if (isFirst) {
			iter = array->begin();
			array->insert(iter, value);
		}
		else {
			iter = lastDelPos;
			if (!iter->isDeleted()) {
				iter->decRefCount();
			}
			array->insert(++iter, value);
		}
		iter--;
	}
	else {
		lastDelPos->setDeleted(false);
		iter = lastDelPos;
	}
	if (hadDelFirst) {
		firstElemIter = iter;
	}
	if (hadDelLast) {
		lastElemIter = iter;
	}
	incIter();
}

list::iterator StrangeIter::getCurIter() {
	return iter;
}

void StrangeIter::incItsRefCount() {
	iter->incRefCount();
}

void StrangeIter::decItsRefCount() {
	iter->decRefCount();
}

bool StrangeIter::isEmpty() {
	return firstElem() == array->end();
}

int sumOfArray(const vector &array) {
	int sum = 0;
	int size = array.size();
	for (int i = 0; i < size; i++) {
		sum += array.at(i);
	}
	return sum;
}

class MaxDivHelper{
public:
	MaxDivHelper(list &array, vector &result, int groupSize, list::iterator &iter);
	bool maxDivFun(int preSize, vector &preArray);
	void setGroupSize(int groupSize);
	void setStart();
private:
	list &array;
	vector &result;
	int groupSize;
	list::iterator &iter;
	list::iterator firstElemIter;
	list::iterator lastElemIter;
};

MaxDivHelper::MaxDivHelper(list &array, vector &result, int groupSize, list::iterator &iter) : array(array), result(result), groupSize(groupSize), iter(iter) , firstElemIter(array.begin()), lastElemIter(array.end()){
	lastElemIter--;
}

void MaxDivHelper::setGroupSize(int groupSize) {
	this->groupSize = groupSize;
	iter = array.begin();
}

void MaxDivHelper::setStart() {
	iter = firstElemIter;
}

bool MaxDivHelper::maxDivFun(int preSize, vector &preArray) {
	while (iter != array.end()) {
		if ((preSize + iter->getValue()) <= groupSize) {
			preArray.push_back(iter->getValue());
			StrangeIter autoInsertIter(iter, &array, firstElemIter, lastElemIter);
			autoInsertIter.erase();
			if ((preSize + preArray.back()) == groupSize) {
				if (autoInsertIter.isEmpty()) {
					result.push_back(preArray);
					return true;
				}
				else {

					list::iterator retIter = lastElemIter;
					while ((--lastElemIter)->isDeleted());
					vector grpArray(1, retIter->getValue());
					bool hadDel = false;
					if (retIter->getRefCount() > 0) {
						retIter->setDeleted(true);
					}
					else {
						hadDel = true;
						array.erase(retIter++);
					}
					setStart();
					if (this->maxDivFun(grpArray.at(0), grpArray)) {
						result.push_back(preArray);
						return true;
					}
					if (hadDel) {
						array.insert(retIter, grpArray.at(0));
						lastElemIter = --retIter;
					}
					else {
						retIter->setDeleted(false);
						lastElemIter = retIter;
					}
				}
			}
			else {
				if (maxDivFun(preSize + preArray.back(), preArray))
					return true;
			}
			autoInsertIter.insert(preArray.back());
			preArray.pop_back();
		}
		else
			break;
	}
	return false;
}

void maxDiv(const vector &array, vector &result) {
	if (array.empty())
		return;
	list retList(array.begin(), array.end());
	retList.sort();
	int maxNum = retList.back().getValue();
	vector preArray(1, maxNum);
	if (retList.size() == 1) {
		result.push_back(preArray);
		return;
	}
	retList.pop_back();
	int sum = sumOfArray(array);
	if (sum % maxNum == 0) {
		result.push_back(preArray);
		int n = 0;
		while (retList.back().getValue() == maxNum) {
			result.push_back(preArray);
			retList.pop_back();
			if (retList.empty())
				return;
			n++;
		}
		preArray.at(0) = retList.back().getValue();
		retList.pop_back();
		MaxDivHelper maxDivHelper(retList, result, maxNum, retList.begin());
		if (maxDivHelper.maxDivFun(preArray.at(0), preArray)) {
			return;
		}
		retList.push_back(preArray.at(0));
		for (; n != 0; n--) {
			retList.push_back(maxNum);
		}
		preArray.at(0) = maxNum;
		result.clear();
	}
	MaxDivHelper maxDivHelper(retList, result, maxNum, retList.begin());
	for (int m = sum/maxNum; m > 0; m--) {
		if (sum % m == 0 ) {
			maxDivHelper.setGroupSize(sum / m);
			if (maxDivHelper.maxDivFun(preArray.at(0), preArray))
				break;
		}
	}
}

    我的测试代码还是和以前一样很简单,现在暂时想不到什么比较好的测试代码。

int main() {
	int a[10000];
	//int a[] = { 1, 2, 4, 5, 100 };
	//int a[] = { 1, 1, 1, 1, 1, 1 };
	//int a[] = { 3, 3, 4, 6, 2 };
	//rand();
	for (int i = 0; i < (sizeof(a) / sizeof(int)); i++) {
	//	a[i] = i + 1;
		if (i % 2 != 0)
			a[i] = 1000 - a[i - 1];
		else
			while ((a[i] = (rand() % 1000)) <= 0);
	}
	vector array(a, a + (sizeof(a)/sizeof(int)));
	vector result;
	maxDiv(array, result);
	cout << "{";
	int resultSize = result.size();
	for (int i = 0; i < resultSize; i++) {
		if (i != 0)
			cout << ", ";
		cout << "{";
		vector group = result.at(i);
		int groupSize = group.size();
		for (int j = 0; j < groupSize; j++) {
			if (j != 0)
				cout << ", ";
			cout << group.at(j);
		}
		cout << "}";
	}
	cout << "}";
	cout << "\n";
	cout << "The max group num that can divide to have same sum group is: " << resultSize;
	return 0;
}

好像跑完上面这段代码花了几毫秒的时间吧。数据再大就堆栈溢出了。


当前标题:一个整数数组,长度为n,将其分为m份,使各份的和相等,求m.(下)
文章地址:http://myzitong.com/article/ihdeep.html