赞
踩
三个柱子: A, B, C 盘子数: n 1. 通过整体思想,把n-1看为一个整体,目的显而易见 把 n-1 从 A 移到 B 把 最大的 从 A 移到 C 把 n-1 从 B 移到 C 2. 其中比较费解的就是: n-1如何从A移到B的 n-1又是如何从B移到C的。 3. 解释n-1如何从A移动B 把 n-2 从 A 移到 C 把 最大的 从 A 移到 B 把 n-2 从 C 移到 B 4. 解释n-1如何从B移动C 把 n-2 从 C 移到 A 把 最大的 从 C 移到 B 把 n-2 从 A 移到 B 1的步骤可以看作是 从A移到C 3的步骤可以看作是 从B移到A 4的步骤可以看作是 从C移到B 根据这些我们可以建立通用的函数: move(int nNumb, string strFrom, string strTo); 参数: nNumb 移动个数 strFrom 从哪移动 strTo 移到哪去 问题就可以概括为: { move(n-2, "A", "C") { move(n-1, "A", "B") { move(1, "A", "B") { { move(n-2, "C", "B") move(n, "A", "C") { move(1, "A", "C") ... { { move(n-2, "B", "A") { move(n-1, "B", "C") { move(1, "B", "C") { move(n-2, "A", "C") 由上又可以看出部分结构的组成,通过这部分结构,可以看出这就是一个递归体: { move(n-1, Begin, Other) move(n, Begin, End) { move(1, Begin, End ) { move(n-1, Other, End ) 那么递归的终止条件在哪呢?我们按照这个步骤推演到最后,结构类似如下: { move(1, Begin, Other) move(2, Begin, End) { move(1, Begin, End ) { move(1, Other, End ) 显而易见的,move(1, ..., ...);没有再执行下去的必要。 所以这也就成为了递归的终止条件。
代码如下:
#include <iostream> #include <vector> #include <algorithm> #include <tchar.h> using std::max_element; using std::cout; using std::endl; using std::vector; using std::string; static int nStep = 0; struct HanNuoTa { string strName; // 塔名 vector<int> vecData; // 塔内数据 }; HanNuoTa GetTaByName(const string & strName, const HanNuoTa& A, const HanNuoTa& B, const HanNuoTa& C) { if (strName.compare(A.strName) == 0) { return A; } else if (strName.compare(B.strName) == 0) { return B; } else if (strName.compare(C.strName) == 0) { return C; } } void PrintData(const HanNuoTa& A, const HanNuoTa& B, const HanNuoTa& C) { int nNumb[] = { A.vecData.size(), B.vecData.size(), C.vecData.size() }; int nMax = *max_element(nNumb, nNumb + 3); if (nStep == 0) { cout << "开始:" << endl; } else { cout << "第" << nStep << "步" << endl; } cout << "A" << "\tB" << "\tC" << endl; nStep++; HanNuoTa ATemp = GetTaByName("A", A, B, C); HanNuoTa BTemp = GetTaByName("B", A, B, C); HanNuoTa CTemp = GetTaByName("C", A, B, C); for (int i = 0; i < nMax; i++) { cout << (ATemp.vecData.size() > i ? ATemp.vecData.at(i) : 0) << "\t"; cout << (BTemp.vecData.size() > i ? BTemp.vecData.at(i) : 0) << "\t"; cout << (CTemp.vecData.size() > i ? CTemp.vecData.at(i) : 0) << endl; } cout << endl; } void Move(const int nNumb, HanNuoTa& stuFrom, HanNuoTa& stuTo) { stuTo.vecData.insert(stuTo.vecData.begin(), stuFrom.vecData.begin(), stuFrom.vecData.begin() + nNumb); stuFrom.vecData.erase(stuFrom.vecData.begin(), stuFrom.vecData.begin() + nNumb); } //************************************************** // @参数:nNumb 移动数量 // A 开始移动的塔 // B 途径的塔 // C 结束的塔 //************************************************** void HanNuo(const int nNumb, HanNuoTa& A, HanNuoTa& B, HanNuoTa& C) { if (nNumb == 1) { Move(nNumb, A, C); PrintData(A, B, C); } else { HanNuo(nNumb - 1, A, C, B); HanNuo(1, A, B, C); HanNuo(nNumb - 1, B, A, C); } } int main(int argc, const char* argv[]) { HanNuoTa A, B, C; A.strName = "A"; A.vecData = { 1, 2, 3 }; B.strName = "B"; C.strName = "C"; PrintData(A, B, C); HanNuo(A.vecData.size(), A, B, C); }
测试结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。