C++ 递归策略

一、汉诺塔问题

1.问题描述

有a、b、c三个塔柱,8个圆盘在塔柱a上,大小随高度增加而减小,将8个圆盘从塔柱a移动到塔柱b,遵循以下规则:

  1. 每次只移动一个圆盘
  2. 不允许将大圆盘移动到小圆盘之上

2.问题框架

在用递归解决此问题时,递归程序应包含以下参数:

  1. 需要移动圆盘数量
  2. 开始的塔柱名字
  3. 最终所在的塔柱名字
  4. 临时储存圆盘的塔柱名字

据此得到如下函数原型:

void moveTower(int n, char start, char finish, char tmp);

3.递归策略

  1. 将最上面的N-1个圆盘从开始所在的塔柱移动到临时塔柱上
  2. 将最底下的一个圆盘从开始所在的塔柱移动到最终所在塔柱上
  3. 将N-1个圆盘从临时塔柱移回到最终所在塔柱上

4.编码方案

操作输出函数:

void moveSingleDisk(char start, char finish) {
	cout << strat << "->" << finish << endl;
}

具体实现函数:

void moveTower(int n, char start, char finish, char tmp) {
	if (n == 1) {
		moveSingleDisk(start, finish);
	}
	else {
		moveTower(n - 1, start, tmp, finish);
		moveSingleDisk(start, finish);
		moveTower(n - 1, tmp, finish, start);
	}
}

二、子集求和问题

1.问题描述

给定一个整数集合和一个目标值,确定是否可以找到这个整数集合的一个子集,子集的和等于指定的目标值
其判定函数如下:

bool subsetSumExists(set<int>& set, int target);

2.递归策略及实现

选择一个元素,然后将其从集合中删除,创建一个更小的集合。

bool subsetSumExists(set<int>& ji_he, int target) {
	if (ji_he.empty()) {
		return target == 0;
	}
	else {
		int element = *ji_he.begin();
		ji_he.erase(element);
		set<int> rest = ji_he;
		return subsetSumExists(rest, target) || subsetSumExists(rest, target - element);

	}
}

这个递归策略包含两个分支,一种包含特定的元素,另一种不包含该特定元素,可以称其为包含/排除模式,在涉及数组和字符串的应用中应注意识别。

三、字符排列

对于一个给定的字符集合可以产生其所有的排列组合。
实现函数如下:

set<string> generatePermutations(string str) {
	set<string> result;
	if (str == "") {
		result.insert("");
	}
	else {
		for (int i = 0; i < str.length(); i++) {
			char ch = str[i];
			string rest = str.substr(0, i) + str.substr(i + 1);
			for (string s : generatePermutations(rest)) {	
				result.insert(ch + s);
			}
		}
	}
		return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值