084day(递归例题(全排列和2的幂次方表示)的学习)

172210704111-陈国佳总结《2018年1月2日》【连续084天】

标题:递归例题(全排列和2的幂次方表示)的学习;

内容:

A.全排列:
总时间限制: 1000ms 内存限制: 65536kB
描述
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列。

输入
输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
输出
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:

已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。
样例输入
abc
样例输出
abc
acb
bac
bca
cab
cba

以前曾经尝试过这题,但当时并未成功,今天结合所给代码来复习这题:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
const int M = 8;
char str[M];
char permutation[M];
bool used[M] = {0};
int L = 0;
void Permutation(int n)
{	
	if( n == L ) {
		permutation[L] = 0;
		cout << permutation << endl;
		return ;
	}
	for(int i = 0;i < L; ++i) {
		if( !used[i]) {
			used[i] = true;
			permutation[n] = str[i];
			Permutation(n+1);
			used[i] = false;
		}
	}
}
int main()
{
	cin >> str;
	L = strlen(str);
	sort(str,str+L);
	Permutation(0);
	return 0;	
}
1)首先,我们可以看到主程序中直接使用了sort函数,由于输出结果与输入顺序毫无关联,所以可用sort来直接简化;

2)由于是递归题目,所以我们为了解析函数的工作原理可以堆栈来进行解析,带入最简的abc,(也可以直接调试,这里是为了加深对栈的理解)

当输入abc时,L=3,然后进入递归函数,

第一层:i=0,used[0]=true,p[0]=str[0]=a;

第二层:i=1,used[1]=true,p[1]=str[1]=b;

第三层:i=2,used[2]=true,p[2]=str[2]=c;

栈顶:   边界条件,输出"abc";

此时,消栈:消除了栈顶和第三层,同时,第二层又产生了第三层:

第二层: used[1]=false, i=2,used[2]=true,p[1]=str[2]=c;

第三层:i=1,used[1]=true,p[2]=str[1]=b;

栈顶: 输出"acb";

.......

大致思路如上,感觉自己的递归还不是太熟悉,需要练习;

B.2的幂次方表示

总时间限制: 1000ms 内存限制: 65536kB
描述
任何一个正整数都可以用2的幂次方表示。例如:

137=27+23+20

同时约定方次用括号来表示,即ab可表示为a(b)。由此可知,137可表示为:

2(7)+2(3)+2(0)

进一步:7=22+2+20(21用2表示)

3=2+20

所以最后137可表示为:

2(2(2)+2+2(0))+2(2+2(0))+2(0)

又如:

1315=210+28+25+2+1

所以1315最后可表示为:

2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

输入
一个正整数n(n≤20000)。
输出
一行,符合约定的n的0,2表示(在表示中不能有空格)。
样例输入
137
样例输出
2(2(2)+2+2(0))+2(2+2(0))+2(0)

示例代码如下:

#include <iostream>
using namespace std;

int pos[32];
//8758
inline int GetBit(int n,int i)
{
	return (n >> i ) & 1;
}
void Print(int n) {
	bool first = true;
	for(int i = 15; i >= 0; --i) {
		
		if( GetBit(n,i)) {
			if(! first ) {
				cout << "+" ;
			}
			else 
				first = false;
			if( i == 0)
				cout << "2(0)" ;
			else if( i == 1)
			 	cout << "2";
			else {
				cout << "2(";
				Print(i);
				cout << ")";
			}
		}
	}
}
int main()
{
	int n;
	cin >> n; 
	Print(n);
	return 0;
}
这道题的难点在于如何把一个整数的最大的2的幂次方数找出来,但我们发现,所给3代码直接使用了位运算,将所给数当作二进制数,而一个二进制数的最大的2的幂次方直接可以用它的最高位i来表示,2^i,看到2的次方,应该立马联想到二进制,这应该是学习计算机的基本素养,以后会多加注意;

代码现在看来就非常简单了,递归函数的if(!first)是为了判断最高位的位置,之后便是递归运算,直到边界条件为止。

要多思考递归。



明日计划:学习;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值