C++ 子集和,带回溯和类
给定一个整数和一个数的序列,程序必须说明该序列中是否存在对该数求和的协同运算。例如: 输入:12345#6 输出:true(因为1+5=6,或2+4=6,或1+2+3=6) 找到什么解决方案并不重要,只要有解决方案 输入:12345#100 输出:false。所有这些数字的总和都不是100 现在,输入:C++ 子集和,带回溯和类,c++,algorithm,backtracking,C++,Algorithm,Backtracking,给定一个整数和一个数的序列,程序必须说明该序列中是否存在对该数求和的协同运算。例如: 输入:12345#6 输出:true(因为1+5=6,或2+4=6,或1+2+3=6) 找到什么解决方案并不重要,只要有解决方案 输入:12345#100 输出:false。所有这些数字的总和都不是100 现在,输入: 243 5 35 24 412 325 346 24 243 432 # 1000 我要走了 main: malloc.c:2401: sysmalloc: Assertion `(old_t
243 5 35 24 412 325 346 24 243 432 # 1000
我要走了
main: malloc.c:2401: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
当它被认为是假的时候。
我必须使用3个类。解决方案、解决方案和候选方案
解算器只调用回溯方法。
解决方案有一个可能的解决方案。
Candidate具有正在查找的序列号的索引
我不明白如何使用Solution类的integer _lvl在不同的候选对象之间移动。
类解算器是正确的。错误必须在解决方案类和候选项中
我的问题是,我必须如何使用候选人和_lvl来检查可能的解决方案?
我应该如何在解决方案类中实现以下方法:
可接受、完整、无脂、无脂
我得到了错误的答案和超出范围的错误
class solver
{
public:
solver();
bool solve(const solution &initial);
solucio getSolution() const;
private:
void findASolution();
bool _found;
solution _sol;
};
解算器
bool solver::solve(const solution &initial)
{
_found = false;
_sol = initial;
findASolution();
return (_found);
}
void solver::findASolution()
{
candidat iCan = _sol.inicializateCandidats();
while ((not iCan.isEnd()) and (!_found))
{
if (_sol.acceptable(iCan)) {
_sol.anotate(iCan);
if(not _sol.complet()) {
findASolution();
if (!_found) {
_sol.desanotate(iCan);
}
}
else {
_found = true;
}
}
iCan.next();
}
}
这门课应该是正确的。我在课程解决方案和候选人方面有困难。类解决方案有5种重要方法:可接受、完整、inicializateCandidates()、anotate和desanotate
如果候选人可以成为解决方案的一部分,则“可接受”为真。
如果找到解决方案,则完成。
指定以保存可能的候选人。
删除注释以删除不再是解决方案一部分的候选项。
inicializateCandidates包含候选构造函数
solution();
solution(const int sequence[], const int &n, const int &sum) {
_searchedSum = sum;
_n = n;
_sum = 0;
_lvl = 0;
reserve(); // bad_alloc. Makes space for vectors
for (int i = 0; i < n; i++) {
_sequence[i] = sequence[i];
_candidates[i] = - 1;
}
solution(const solution &o);
~solution();
solution & operator=(const solution &o);
candidat inicializateCandidats() const {
return candidat(_n);
}
bool acceptable(const candidat &iCan) const {
return (_sum + _sequence[iCan.actual()] <= _searchedSum);
}
bool complet() const {
return (_sum == _searchedSum);
}
void show() const;
void anotate(const candidat &iCan) {
_niv++;
_candidates[_niv] = iCan.actual();
_sum += _sequence[iCan.actual()];
}
void desanotate(const candidat &iCan) {
_candidates[_niv] = - 1;
_sum -= _sequence[iCan.actual()];
_niv--;
}
private:
// memory gestion methods
void solution::reserve() {
_sequence = new int[_n];
_candidates = new int[_n];
}
int *_sequence; // original sequence
int *_candidates; // possible subsequence part of solution
int _n; // size of the array
int _lvl; // lvl of the tree generated by backtracking
int _searchedSum;
int _sum; // total sum of actual solution
我已经找到了一个可能的解决方案,但它根本不符合要求 在类解算器中,我创建了一个属性来保存前一个候选项,在-1处初始化 候选类的构造函数按以下方式更改:
candidat::candidat(const int &n, const int &ant) {
_size = n;
_iCan = ant + 1;
}
在solution.h中,现在有一个布尔数组来保存可以作为解决方案一部分的候选项_lvl被消除
在solver.cpp中,回溯略有更改,但不应更改
bool solver::solve(const solution &initial) {
_found = false;
_ant = -1;
_sol = initial;
findASolution();
return (_found);
}
void solver::findASolution() {
**candidat iCan = _sol.inicializateCandidats(_ant);**
while ((not iCan.isEnd()) and (!_found))
{
if (_sol.acceptable(iCan)) {
_sol.anotate(iCan);
if(not _sol.complet()) {
**_ant = iCan.actual();**
findASolution();
if (!_found) {
_sol.desanotate(iCan);
}
}
else {
_found = true;
}
}
iCan.next();
}
}
人们注意到了分歧
但这并不是最好的解决方案。正确的解决方案应该是使用_lvl属性。解算器类不应该知道解的属性。就看它是否被找到。你的问题是什么?如果您需要错误方面的帮助,您应该将其包括在问题中。“代码根本没有翻译,但我相信每个人都会理解它。”对不起,没有。最好用英语编写代码,以便其他人可以阅读它。为向量腾出空间——你为什么不直接用
std::vector
而不是自己构建向量类?这是家庭作业吗?(这没什么错,我只是想知道,对于原则上只需要几行代码的东西,使用3个类的要求从何而来)是的,这是Homehowk。所有内容都经过了翻译,并解释了3个类应该如何工作。解算器是正确的,候选,可能(不确定)太。答案肯定不是。
bool solver::solve(const solution &initial) {
_found = false;
_ant = -1;
_sol = initial;
findASolution();
return (_found);
}
void solver::findASolution() {
**candidat iCan = _sol.inicializateCandidats(_ant);**
while ((not iCan.isEnd()) and (!_found))
{
if (_sol.acceptable(iCan)) {
_sol.anotate(iCan);
if(not _sol.complet()) {
**_ant = iCan.actual();**
findASolution();
if (!_found) {
_sol.desanotate(iCan);
}
}
else {
_found = true;
}
}
iCan.next();
}
}