0
点赞
收藏
分享

微信扫一扫

C语言错排问题

今天,复习一下按字典序输出错排序列
思路探索:尝试将a放在1号位上,若a!=1且没有放在别的位置上,就将a放在1号位上并作标记;尝试将b放在2号位上,若b!=2且不位于其他位置上,将b放在2号位上,做标记,尝试将c放在3号位上,若c!=3且不位于其他位置上。下面来看一个例子,比如说我要得到1 2 3的错排序列,将2放在1号位,1放在2号位,3放在3号位,呃,出错了,不算,重来!说明21开头得不到错排序列。将2放在1号位,3放在2号位,1放在3号位,不行!1不能放在3号位,因为1被使用的标志是在第2位放1时被标记的,这说明啥?说明每次循环结束后就要取消有该循环带上的标记。
先敲一段字典序全排列输出错排序列的吧

//以字典序求全排列,并只输出错排序列
//思路:输出全排列,不是错排不输出
#include<stdio.h>
#include<string.h>
#define N 100
void swap(char *p,char *q)//如果不是全局变量,一定设计的参数是指针类型 
{
    char ch;
    ch=*p;
    *p=*q;
    *q=ch;
}
//逆置以p,q为首尾地址的字符串 
void reverse(char *p,char *q)
{//头指针,尾指针 
    while(p<q)
        swap(p++,q--);//调用函数做的第一件事,实参求解,从右往左执行
         //ch=*p;*p=*q;*q=ch;p++;q--;
}

void sort(char *s)
{
    char *p,*q,ch;
    int n=strlen(s);

    for(p=s;p<=s+n-2;p++)//首地址传给字符指针 指向第一个 模拟n-1趟 s+n是\0的下标  
        for(q=p+1;q<=s+n-1;q++)//s+n-1 倒数第一个字符 
    //选择法排序 
    if(*p>*q)
        swap(p,q);
}
int fun(char *s,char *t)
{//s指向的是准备判断的字符序列,t是准备错排的原始序列,只要有一个字符在正确位置上,就不是错排 
    while(*s)//*s!=0 *s!='\0' 
    {
        if(*s==*t)//相等说明在正确位置上,不是错排 
            return 1; 
        s++;
        t++;
    }
    return 0;
 } 

int permutation(char *s,char *t)
{
    char *p,*q;
    //对比字典序全排列,初值改变为0,因为字典序全排列已经输出最小串
    int count=0;

    while(1)
    {
        p=s+strlen(s)-1;
        //从右往左找出第一对相邻的升序的元素

        while(*(p-1)>*p)
        {
            p--;//不存在相邻的升序元素,即s为最大串
            if(p==s)
                return count; 
         }
         q=p-1;//q为交换点
         p=s+strlen(s)-1;//从右往左找到第一个大于*q的元素
         while(*p<*q)
         {
            p--;
          }
          swap(p,q);
          reverse(q+1,s+strlen(s)-1);

          if(!fun(s,t))
          {
            puts(s);
            count++;
           } 
     } 
}
int main()
{
    char s[N],t[N];

    int n;

    gets(s);
    if(s[0]==0)
        return 0;
    if(s[1]==0)
    {
        puts(s);
        return 0;
    }
    strcpy(t,s);
    sort(s);
    printf("\n");

    n=permutation(s,t);
    printf("%d\n",n);

    return 0;
}
举报

相关推荐

0 条评论