算法:找出字符串中包含的字符可以进行的所有不同组合解决思路
算法:找出字符串中包含的字符可以进行的所有不同组合
例: 字符串 abccd 中可能的组合有:ab,ac,bc,cc,abd 等 ...
好久没用C了,语法都有点忘了,我考虑是否应该用递归。
------解决方案--------------------
穷举法
------解决方案--------------------
求一个字符串序列的全排列,按字典顺序排序,要求不能够出现相同的情况是不能够出现的。例如:对于串aabc,其中每一个排列不能重复出现。
串的最大长度为n
解题思路
本题是ACM southwestern European Regional的一道题目(号称是最简单的题),乍一看题目我也觉得很简单,于是DFS+记忆状态,企图用硬搜通过这道题,结果TLE+OLE。后来分析发现我穷搜的答案也不对(比如我把aabc这个状态输出了两遍都不止……),其实OLE应该是Wrong Answer,只不过因为硬搜把许多重复的情况也输出了出来,所以Output Limit Exceeded。
重要部分的代码如下:
void search(long len)
{
long i;
long j;
char temp;
if (len > = n_s) {
print();//输出
}
else {
search(len+1);//第一个字符与第一个字符之间不用交换
for (i = len + 1 ; i < strlen(s) ; i++) {
if (s[i] != s[len]){
temp = s[i];
s[i] = s[len];
s[len] = temp; //swap
search(len+1);
}
}
//恢复
temp = s[len];
for (i = len ; i < strlen(s) - 1; i++){
s[i] = s[i + 1];
}
s[strlen(s) - 1] = temp;
}
}
详细请参见
http://www.cfannet.com/bbs/dispbbs.asp?boardID=11&ID=92&page=1
------解决方案--------------------
对于abccd,做如下表示: x1x2x3x4x5 xi=0 or 1 。
xi=1时,输出这一位上的字母。比方说,如果x1=1,则输出a。
然后,考虑如何获得abccd的子串。取或不取任一位都将得到一个新的子串(不考虑重复)
所以,abccd共有2^5=32个子串,包括空字符串和其本身。
所以求子串的过程就是得到x1x2x3x4x5所有的可能值,共有个32。
求子串的过程描述为
00000-> bitarray
for i=0 to 32
do bitarray + 1.
output substring according to bitarray. 1 to output, 0 do to do nothing
end
Remove duplicated substring.
加法为2进制加法, 00001 + 1 = 00010
这样,就得到了5位二进制数的排列, 也就得到了所有的子串
------解决方案--------------------
晕~~我笔试就考的这道题,可惜我做不来,早点让我看到就好了
例: 字符串 abccd 中可能的组合有:ab,ac,bc,cc,abd 等 ...
好久没用C了,语法都有点忘了,我考虑是否应该用递归。
------解决方案--------------------
穷举法
------解决方案--------------------
求一个字符串序列的全排列,按字典顺序排序,要求不能够出现相同的情况是不能够出现的。例如:对于串aabc,其中每一个排列不能重复出现。
串的最大长度为n
解题思路
本题是ACM southwestern European Regional的一道题目(号称是最简单的题),乍一看题目我也觉得很简单,于是DFS+记忆状态,企图用硬搜通过这道题,结果TLE+OLE。后来分析发现我穷搜的答案也不对(比如我把aabc这个状态输出了两遍都不止……),其实OLE应该是Wrong Answer,只不过因为硬搜把许多重复的情况也输出了出来,所以Output Limit Exceeded。
重要部分的代码如下:
void search(long len)
{
long i;
long j;
char temp;
if (len > = n_s) {
print();//输出
}
else {
search(len+1);//第一个字符与第一个字符之间不用交换
for (i = len + 1 ; i < strlen(s) ; i++) {
if (s[i] != s[len]){
temp = s[i];
s[i] = s[len];
s[len] = temp; //swap
search(len+1);
}
}
//恢复
temp = s[len];
for (i = len ; i < strlen(s) - 1; i++){
s[i] = s[i + 1];
}
s[strlen(s) - 1] = temp;
}
}
详细请参见
http://www.cfannet.com/bbs/dispbbs.asp?boardID=11&ID=92&page=1
------解决方案--------------------
对于abccd,做如下表示: x1x2x3x4x5 xi=0 or 1 。
xi=1时,输出这一位上的字母。比方说,如果x1=1,则输出a。
然后,考虑如何获得abccd的子串。取或不取任一位都将得到一个新的子串(不考虑重复)
所以,abccd共有2^5=32个子串,包括空字符串和其本身。
所以求子串的过程就是得到x1x2x3x4x5所有的可能值,共有个32。
求子串的过程描述为
00000-> bitarray
for i=0 to 32
do bitarray + 1.
output substring according to bitarray. 1 to output, 0 do to do nothing
end
Remove duplicated substring.
加法为2进制加法, 00001 + 1 = 00010
这样,就得到了5位二进制数的排列, 也就得到了所有的子串
------解决方案--------------------
晕~~我笔试就考的这道题,可惜我做不来,早点让我看到就好了