您的位置:首页 > 其它

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

2018-01-02 23:42 260 查看
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
= 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)是为了判断最高位的位置,之后便是递归运算,直到边界条件为止。

要多思考递归。

明日计划:学习;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: