C语言练习题:输入n个字符串,将它们按字典顺序输出。(请用数组的指针和指针数组两种方法做) 求计算
求计算机大神帮忙解答啊,指针这章真的不懂啊!吓哭了~~ 展开
// 下面是字典序:
#include<stdio.h>
#include <string.h>
void swap(char *a,char *b)
{
char temp=*a;
*a = *b;
*b = temp;
}
int nextperm(char a[], int n) // 字典序排列(从升序到降序排列(也可从降序到升序))基于ASCII码准则
{
int i,j,k=-1,l;
for(i=0;i<n-1;i++) // 从前向后方向扫描,找到最后一对为升序的相邻元素(如果不存在,则所有排列已完成)
{
if(a[i]<a[i+1])
k=i; // 把最后一对为升序的相邻元素(靠左边)的下标赋值给k
}
if (k>=0)// k>=0说明找到一对为升序的相邻元素
{
l=-1;
for(i=0;i<n;i++)
{
if(a[k]<a[i]) l=i;
}
swap(&a[k],&a[l]);// 交换下标为k和l的元素
for(i=k+1;i<n;i++)// 扭转索引k+1后面的元素
{
j = n - i + k;
if (i >= j) break;
swap(&a[i],&a[j]);
}
}
if (k==-1) return 0;
for(i=0;i<n;i++) printf("%c",a[i]);
printf("\n");
return 1;
}
int main()
{
int i, lens;
char ch[10];
printf("Please input string (longest 10):");
scanf("%s",ch);
lens=strlen(ch);
for(i=0;i<lens;i++)printf("%c",ch[i]);
printf("\n");
while (nextperm(ch,lens));
return 0;
}
注:该算法参考了14世纪印度数学家 纳拉亚纳潘迪特的思想,
我们伟大的数学家纳拉亚纳潘迪特的字典序思想原文(英文版的)如下:
-- 国内很多人使用这种技术但他(她)们并不知道该算法思想的创始者是谁?因为网上所看到的帖子个个都打着原创,其实不然,所以我对此表示很遗憾.因为真正的原创是追溯到14世纪印度数学家 纳拉亚纳潘迪特
下面是该算法的英文简介(目前手头上只有数学家的英文资料没有中文的,所以将就着看):
Generation in lexicographic order:
There are many ways to systematically generate all permutations of a given sequence.[16] One classical algorithm, which is both simple and flexible, is based on finding the next permutation in lexicographic ordering, if it exists. It can handle repeated values, for which case it generates the distinct multiset permutations each once. Even for ordinary permutations it is significantly more efficient than generating values for the Lehmer code in lexicographic order (possibly using the factorial number system) and converting those to permutations. To use it, one starts by sorting the sequence in (weakly) increasing order (which gives its lexicographically minimal permutation), and then repeats advancing to the next permutation as long as one is found. The method goes back to Narayana Pandita in 14th century India, and has been frequently rediscovered ever since.[17]
The following algorithm generates the next permutation lexicographically after a given permutation. It changes the given permutation in-place.
Find the largest index k such that a[k] < a[k + 1]. If no such index exists, the permutation is the last permutation.
Find the largest index l such that a[k] < a[l].
Swap the value of a[k] with that of a[l].
Reverse the sequence from a[k + 1] up to and including the final element a[n].
For example, given the sequence [1, 2, 3, 4] which starts in a weakly increasing order, and given that the index is zero-based, the steps are as follows:
Index k = 2, because 3 is placed at an index that satisfies condition of being the largest index that is still less than a[k + 1] which is 4.
Index l = 3, because 4 is the only value in the sequence that is greater than 3 in order to satisfy the condition a[k] < a[l].
The values of a[2] and a[3] are swapped to form the new sequence [1,2,4,3].
The sequence after k-index a[2] to the final element is reversed. Because only one value lies after this index (the 3), the sequence remains unchanged in this instance. Thus the lexicographic successor of the initial state is permuted: [1,2,4,3].
Following this algorithm, the next lexicographic permutation will be [1,3,2,4], and the 24th permutation will be [4,3,2,1] at which point a[k] < a[k + 1] does not exist, indicating that this is the last permutation.