1.字串的全排列。
全排列就是從第乙個數起每個數分別與它後面的數交換。
遞迴實現
從集合中依次選出每乙個元素,作為排列的第乙個元素,然後對剩餘的元素進行全排列,如此遞迴處理,從而得到所有元素的全排列。以對字串abc進行全排列為例,我們可以這麼做:以abc為例
固定a,求後面bc的排列:abc,acb,求好後,a和b交換,得到bac
固定b,求後面ac的排列:bac,bca,求好後,a和c交換,得到cba
固定c,求後面ba的排列:cba,cab。**可如下編寫所示:
template void calcallpermutation_r(t perm, int first, int num)
for (int i = first; i < first + num; ++i)
}
或者這樣:
#includeusing namespace std;
#includevoid permutation(char* pstr, char* pbegin) }}
int main(void)
字典序排列
把公升序排列作為當前排列開始,然後依次計算當前排列的下乙個字典序排列。
對當前排列從後向前掃瞄,找到一對為公升序的相鄰元素,記為i和j(i < j)。如果不存在這樣一對為公升序的相鄰元素,則所有排列均已找到,演算法結束;否則,重新對當前排列從後向前掃瞄,找到第乙個大於i的元素k,交換i和k,然後對從j開始到結束的子串行反轉,則此時得到的新排列就為下乙個字典序排列。這種方式實現得到的所有排列是按字典序有序的,這也是c++ stl演算法next_permutation的思想。演算法實現如下:
template void calcallpermutation(t perm, int num)
if (i < 0)
break; // 已經找到所有排列
int k;
for (k = num - 1; k > i; --k)
swap(perm[i], perm[k]);
reverse(perm + i + 1, perm + num);
} }
去掉重複的全排列的遞迴實現
去重的全排列就是從第乙個數字起每個數分別與它後面非重複出現的數字交換。
#includeusing namespace std;
#include//在[nbegin,nend)區間中是否有字元與下標為pend的字元相等
bool isswap(char* pbegin , char* pend)
return true;
}void permutation(char* pstr , char *pbegin)
else
} }}
int main(void)
2.字串的組合。
假設我們想在長度為n的字串中求m個字元的組合。我們先從頭掃瞄字串的第乙個字元。針對第乙個字元,我們有兩種選擇:第一是把這個字元放到組合中去,接下來我們需要在剩下的n-1個字元中選取m-1個字元;第二是不把這個字元放到組合中去,接下來我們需要在剩下的n-1個字元中選擇m個字元。這兩種選擇都很容易用遞迴實現。下面是這種思路的參考**:
#include#include#includeusing namespace std;
#includevoid combination(char *string ,int number,vector&result);
void combination(char *string)
void combination(char *string ,int number , vector&result)
if(*string == '\0')
return ;
result.push_back(*string);
combination(string + 1 , number - 1 , result);
result.pop_back();
combination(string + 1 , number , result);
}int main(void)
或者這樣
#includeusing namespace std;
int a = ;
char str = "abcde";
void print_subset(int n , int s)
bool check(int columnindex , int length)
} return true;
}void permutation(int columnindex , int length , int index)
} else }
}void print(int columnindex , int length)
int main(void)
4.輸入兩個整數n和m,從數列1,2,3...n中隨意取幾個數,使其和等於m,要求列出所有的組合。
#include #include using namespace std;
listlist1;
void find_factor(int sum,int n)
{ //遞迴出口
if(n<=0||sum<=0)
return;
//輸出找到的數
if(sum==n)
{ list1.reverse();
for(list::iterator iter=list1.begin();iter!=list1.end();iter++)
cout<<*iter<<"+";
cout<>sum>>n;
cout<<"所有可能的序列,如下:"<
筆試面試題
1 昨天參加一公司筆試,給幾道演算法題整懵了,其實也不難,但好久沒有碰演算法,只是有思路,要讓我在這麼短的時間內寫出程式來還是不行。2 這裡將其中一道稍微複雜一點的演算法題寫下來,以此小結。3 4 題目描述 5 將n個雞蛋放入到m個籃子中去 n m 保證每個籃子中至少乙個雞蛋,然後指定乙個數x,要求...
面試題 筆試
題1 有如下資料庫表tab 請用乙個 delete 語句,刪除 value 重複的行,每個 value 只保留 id 最小的一行。delete from tab where id notin select from select min id from tab groupby value a 好像有...
筆試面試題
1.書架上有編號為1 19的19本書,從中拿5本,問5本編號都不相鄰的拿法有多少種?使用隔板法,拿掉5本後剩下14塊板,即有15個空,使用組合15份插5份 c15 5 3003 2.1億個資料取前1萬大的整數 演算法思路 a.把1億個資料分成10000個陣列,b.求出10000個陣列的最大值,儲存到...