用C ++解决难题的方法 - 多种多样 [英] Ways to solve a puzzle in C++ -- variety

查看:53
本文介绍了用C ++解决难题的方法 - 多种多样的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个关于指针的小块,要捆绑。用我的尝试

正确的C ++教程(参见FAQ 29.20,是的,我终于开始在

再考虑一下),并且在考虑好的时候示例我出现了

,解决了下面代码中解释的难题,解算器优化了b / b
,这样就不会对状态进行多次分析。


然而,我很快就意识到这可以做得最自然(对我来说,至少
)_without_使用任何指针 - 但也许这不是那么对你来说?


所以现在我对'_our_自然的感兴趣这样做的方法。


请不要先查看旧教程,其中有一个类似的例子,

,因为这可能会影响你的方式选择解决这个问题。


我想你可以在这里将工作代码或URL发布到工作代码中

在这个帖子中,并且能够比较解决方案,请使用下面的规格

不变,除了重命名,缩进等,并修复错误,

如果有的话(规范编译但我避风港) 我试过了。

命名空间nac_puzzle

{

enum RiverSideEnum {left,right}; //我们有一条河流有左岸和右岸。

内联RiverSideEnum对面(RiverSideEnum方面)

{

返回RiverSideEnum(1 - 一边);

}


enum PersonKindEnum {cannibal,nun}; //右边有食人族和修女。

内联PersonKindEnum对面(PersonKindEnum类)

{

返回PersonKindEnum(1 - 种类) );

}


enum {nPersonsOfAKind = 3,maxPerTransfer = 2}; //船最多可容纳2人...


等级状态

{

私人:

unsigned myNCannibalsAtLeft;

unsigned myNNunsAtLeft;

RiverSideEnum myBoatPosition;


public:

State ():myNCannibalsAtLeft(0),myNNunsAtLeft(0),myBoatPosition(右){}

状态(unsigned nCannibalsAtLeft,unsigned nNunsAtLeft,RiverSideEnum aBoatPos)



myNCannibalsAtLeft(nCannibalsAtLeft),

myNNunsAtLeft(nNunsAtLeft),

myBoatPosition(aBoatPos)

{

断言(0< = myNCannibalsAtLeft&& myNCannibalsAtLeft< = nPersonsOfAKind);

断言(0< = myNNunsAtLeft&& myNNunsAtLeft< = nPersonsOfAKind);

断言(myBoatPosition == left || myBoatPosition == right);


断言(!(

n(食人族,左) )+ n(nun,left)== 0&& boatPosition()== left

));
断言(!(

n(食人,右)+ n(尼姑,右)== 0&& boatPosition()== right

));

}


unsigned n(PersonKindEnum类,RiverSideEnum方)const

{

unsigned const nOfKindAtLeft =

(kind ==食人族?myNCannibalsAtLeft:myNNunsAtLeft);

return(side = = left?nOfKindAtLeft:nPersonsOfAKind - nOfKindAtLeft);

}


RiverSideEnum boatPosition()const {return myBoatPosition; }

unsigned nCannibalsAtBoat()const {return n(食人族,boatPosition()); }

unsigned nNunsAtBoat()const {return n(nun,boatPosition()); }


bool isSolution()const

{

返回

n(食人,左)= = nPersonsOfAKind&&

n(nun,left)== nPersonsOfAKind;

}


bool isCannibalisticOrgy()const

{

返回(

n(食人,左)> = n(nun,left)||

n (食人,右)> = n(尼姑,右)

);

}


bool canTransfer(unsigned nCannibals ,未签名的nNuns)

{

返回

!isCannibalisticOrgy()&&

nCannibals< = nCannibalsAtBoat()&&

nNuns< = nNunsAtBoat()&&

0< (nCannibals + nNuns)&& (nCannibals + nNuns)< = maxPerTransfer;

}


无效转移(无符号nCannibals,无符号nNuns)

{

断言(canTransfer(nCannibals,nNuns));


if(myBoatPosition == left)

{

myNCannibalsAtLeft - = nCannibals;

myNNunsAtLeft - = nNuns;

}

else

{

myNCannibalsAtLeft + = nCannibals;

myNNunsAtLeft + = nNuns;

}

myBoatPosition = opposite(myBoatPosition);

}

}; //类状态

} //命名空间nac_puzzle


-

答:因为它弄乱了人们的顺序通常阅读文字。

问:为什么这么糟糕?

A:热门帖子。

问:什么是最多的在usenet和电子邮件中烦人的事情?

I''m writing a little piece on pointers, to be "bundled" with my attempted
correct C++ tutorial (see FAQ item 29.20, yes, I''ve finally started to at
least think about that again), and while thinking of good examples I came up
with the idea of solving the puzzle explained in code below, with the solver
optimized so that a state is never analysed more than once.

However, I soon realized that this could be done most naturally (for me, at
least) _without_ using any pointers -- but perhaps that''s not so for you?

So now I''m interested in what''s _your_ "natural" way to do this.

Please don''t look at the old tutorial first, which has a similar example,
because that could influence the way you choose to tackle the problem.

I''m thinking that you can just post working code or URLs to working code here
in this thread, and to be able to compare solutions, please use the below spec
unchanged except perhaps for renaming, indentation and such, and fixing bugs,
if any (the spec compiles but I haven''t tried it out yet).
namespace nac_puzzle
{
enum RiverSideEnum{ left, right }; // We have a river with a left and right bank.
inline RiverSideEnum opposite( RiverSideEnum side )
{
return RiverSideEnum( 1 - side );
}

enum PersonKindEnum{ cannibal, nun }; // There are cannibals and nuns, on the right.
inline PersonKindEnum opposite( PersonKindEnum kind )
{
return PersonKindEnum( 1 - kind );
}

enum { nPersonsOfAKind = 3, maxPerTransfer = 2 }; // The boat holds max 2 persons...

class State
{
private:
unsigned myNCannibalsAtLeft;
unsigned myNNunsAtLeft;
RiverSideEnum myBoatPosition;

public:
State(): myNCannibalsAtLeft( 0 ), myNNunsAtLeft( 0 ), myBoatPosition( right ) {}

State( unsigned nCannibalsAtLeft, unsigned nNunsAtLeft, RiverSideEnum aBoatPos )
:
myNCannibalsAtLeft( nCannibalsAtLeft ),
myNNunsAtLeft( nNunsAtLeft ),
myBoatPosition( aBoatPos )
{
assert( 0 <= myNCannibalsAtLeft && myNCannibalsAtLeft <= nPersonsOfAKind );
assert( 0 <= myNNunsAtLeft && myNNunsAtLeft <= nPersonsOfAKind );
assert( myBoatPosition == left || myBoatPosition == right );

assert( !(
n( cannibal, left ) + n( nun, left ) == 0 && boatPosition() == left
) );
assert( !(
n( cannibal, right ) + n( nun, right ) == 0 && boatPosition() == right
) );
}

unsigned n( PersonKindEnum kind, RiverSideEnum side ) const
{
unsigned const nOfKindAtLeft =
(kind == cannibal? myNCannibalsAtLeft : myNNunsAtLeft);
return (side == left? nOfKindAtLeft : nPersonsOfAKind - nOfKindAtLeft );
}

RiverSideEnum boatPosition() const { return myBoatPosition; }
unsigned nCannibalsAtBoat() const { return n( cannibal, boatPosition() ); }
unsigned nNunsAtBoat() const { return n( nun, boatPosition() ); }

bool isSolution() const
{
return
n( cannibal, left ) == nPersonsOfAKind &&
n( nun, left ) == nPersonsOfAKind;
}

bool isCannibalisticOrgy() const
{
return (
n( cannibal, left ) >= n( nun, left ) ||
n( cannibal, right ) >= n( nun, right )
);
}

bool canTransfer( unsigned nCannibals, unsigned nNuns )
{
return
!isCannibalisticOrgy() &&
nCannibals <= nCannibalsAtBoat() &&
nNuns <= nNunsAtBoat() &&
0 < (nCannibals + nNuns) && (nCannibals + nNuns) <= maxPerTransfer;
}

void transfer( unsigned nCannibals, unsigned nNuns )
{
assert( canTransfer( nCannibals, nNuns ) );

if( myBoatPosition == left )
{
myNCannibalsAtLeft -= nCannibals;
myNNunsAtLeft -= nNuns;
}
else
{
myNCannibalsAtLeft += nCannibals;
myNNunsAtLeft += nNuns;
}
myBoatPosition = opposite( myBoatPosition );
}
}; // class State
} // namespace nac_puzzle

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

推荐答案

* Alf P. Steinbach:
* Alf P. Steinbach:
并修复错误,如果任何(规范编译,但我还没有尝试过)。
and fixing bugs, if any (the spec compiles but I haven''t tried it out yet).




当然,食人族的标准应该是有的

_more_他们在一边,否则一个人甚至不会开始。即

比较运算符应该是>而不是> =正如我写的...... Grr。 ;-)


-

答:因为它弄乱了人们通常阅读文字的顺序。

问:为什么这么糟糕?

A:热门发布。

问:usenet和电子邮件中最烦人的是什么?



Of course the criterion for cannibals going amok should be that there are
_more_ of them on one side, otherwise one wouldn''t even get started. I.e. the
comparision operator should be ">", not ">=" as I wrote... Grr. ;-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


* Alf P. Steinbach:
* Alf P. Steinbach:
* Alf P. Steinbach:
* Alf P. Steinbach:
并修复bug,如果有的话(规范编译但是我还没有尝试过。)
and fixing bugs, if any (the spec compiles but I haven''t tried it out yet).



当然,食人族的标准应该是,一方面有更多__________,否则就不会甚至没有开始。即
比较运算符应该是>而不是> =正如我写的...... Grr。 ; - )



Of course the criterion for cannibals going amok should be that there are
_more_ of them on one side, otherwise one wouldn''t even get started. I.e. the
comparision operator should be ">", not ">=" as I wrote... Grr. ;-)




bool isCannibalisticOrgy()const

{

return(

n(食人,左)> n(nun,左)&& n(nun,左)> 0 ||

n(食人,右)> n(nun,右) && n(nun,right)> 0

);

}


-

答:因为它弄乱了人们通常阅读文字的顺序。

问:为什么这么糟糕?

A:热门帖子。

问:usenet和电子邮件中最烦人的是什么?



bool isCannibalisticOrgy() const
{
return (
n( cannibal, left ) > n( nun, left ) && n( nun, left ) > 0 ||
n( cannibal, right ) > n( nun, right ) && n( nun, right ) > 0
);
}

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?




Alf P斯坦巴赫写道:

Alf P. Steinbach wrote:
所以现在我对'_our_自然的感兴趣这样做的方式。


你在谈论我们做这个州级或解算器的方式吗?

bool canTransfer(unsigned nCannibals,unsigned nNuns)
{
返回
!isCannibalisticOrgy()&&
nCannibals< = nCannibalsAtBoat()&&
nNuns< = nNunsAtBoat()&&
0< (nCannibals + nNuns)&& (nCannibals + nNuns)< = maxPerTransfer;
}
So now I''m interested in what''s _your_ "natural" way to do this.
Are you talking about our way of doing this state class, or the solver?
bool canTransfer( unsigned nCannibals, unsigned nNuns )
{
return
!isCannibalisticOrgy() &&
nCannibals <= nCannibalsAtBoat() &&
nNuns <= nNunsAtBoat() &&
0 < (nCannibals + nNuns) && (nCannibals + nNuns) <= maxPerTransfer;
}




canTransfer()不检查那边有多少n / c。 ..


干杯,

Andre



canTransfer() dosn''t check how many n/c are left on that side...

Cheers,
Andre


这篇关于用C ++解决难题的方法 - 多种多样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆