【劍指offer】字串的排列

蘭亭風雨發表於2014-05-21

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/26390551


題目描述:

輸入一個字串,按字典序列印出該字串中字元的所有排列。例如輸入字串abc,則列印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。

輸入:

每個測試案例包括1行。

輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字母。

輸出:

對應每組資料,按字典序輸出所有排列。

樣例輸入:
abc
BCA
樣例輸出:
abc
acb
bac
bca
cab
cba
ABC
ACB
BAC
BCA
CAB
CBA

    昨晚折騰了一個晚上,連這一道題目都沒AC,太受打擊了!這裡倒不是演算法的問題,主要是既要考慮輸出的字串按字典序排列,又要去掉重複的字串。本想直接在不儲存所有字串的前提下,直接按照要求輸出字串,但折騰了一晚上,還是決定放棄了,依然是使用最直接的方法,以空間換取結果,將所有的字串儲存到一個字串陣列中,由於全排列後的字串數最大為9!=362880,故開闢一個362900大的字串陣列用來儲存這些字串,而後對這些字串進行排序,先用了選擇排序,通過strcpy字串進行排序,結果爭取,但第三組測試用例超時,無奈,最後還是要用系統自帶的qsort快排函式,這次AC了,順帶也複習了下qsort的用法,瞭解的更深入了些!

    AC程式碼:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

char result[362900][10];
int count = 0; //排列字串的個數

/*
交換兩個字元
*/
void swap(char *a,char *b)
{
	char temp = *a;
	*a = *b;
	*b = temp;
}

/*
對字串str從begin開始的後面的字元進行排列
*/
void Permutation(char *str,int begin)
{
	int len = strlen(str);
	if(begin == len-1)
	{
		strcpy(result[count++],str);
		return;
	}

	int i;
	for(i=begin;i<len;i++)
	{
		swap(&str[begin],&str[i]);
		Permutation(str,begin+1);
		swap(&str[begin],&str[i]);
	}
}

/*
將Permutation封裝起來
*/
void PermutationAllChar(char *str)
{
	if(str == NULL)
		return ;
	Permutation(str,0);
}

/*
比較str1和str2的大小
*/
int myCompare(const void *a,const void *b)
{
	char *s1 = (char *)a;
	char *s2 = (char *)b;
	return strcmp(s1,s2);
}

int main()
{
	char str[10];
	while(gets(str))
	{
		PermutationAllChar(str);

		//快排對字串陣列進行字典排序
		//之前採用選擇排序,並通過複製字串排序,OJ上報超時
		//改用快排,AC。
		qsort(result,count,10*sizeof(char),myCompare);

		//跳過重複字串
		int i;
		for(i=0;i<count;i++)
		{
			if(strcmp(result[i],result[i+1]) == 0)
				continue;
			puts(result[i]);
		}
 
		//下一個字元的排列依然從result陣列的開始處開始存放
		count = 0;
	}
	return 0;
}
/**************************************************************
    Problem: 1369
    User: mmc_maodun
    Language: C
    Result: Accepted
    Time:220 ms
    Memory:8000 kb
****************************************************************/

相關文章