例题3-6 环状序列UVa1584

该题个人觉得很经典,有能学习的地方,在功能的实现上完成了模块化,找到最小位置专门声明了函数less..直接、明了

#include <stdio.h>
#include <string.h>
#define maxn 105
int less(const char* s,int p,int q)
{
    int n = strlen(s);
    for(int j=0;j<n;j++)                        
    //从s[p]、s[q]开始往后依次判断每个字符
        if (s[(j+p)%n] != s[(j+q)%n])           //如果相等就继续循环
            return s[(j+p)%n] < s[(j+q)%n];     //直到找到不同的位置
    return 0;                                   //全相同则是相等
}

int main()
{
    int T;
    char s[maxn];
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",s);
        int ans=0;
        int n = strlen(s);
        for(int i=1;i<n;i++) if(less(s,i,ans)) ans=i;   
//比较所有位置找到最小字母的ans位置,可以理解为找到最小数,而less就是定义了怎么样才是最小
        for(int i=0;i<n;i++) putchar(s[(ans+i)%n]);
        putchar('\n');
    }
    return 0;
}

再奉上mrcrack的做法:

#include <stdio.h>
#include <string.h>
#define maxn 105;
char s[maxn];
char stemp[maxn][maxn];

int main(){
    int T,len,i,mini,count,j;
    char minc;
    scanf("%d",&T);
    while(T--){
        scanf("%s",s);
        len=strlen(s);
        minc=s[0];
        count=0;
        for(i=0;i<len;i++){//找出字典序列最小的字母 
            if(minc>s[i])
                minc=s[i];
        }
        for(i=0;i<len;i++)
            if(minc==s[i]){//根据最小字母,形成不同子串 
                for(j=0;j<len;j++){
                    stemp[count][j]=s[(i+j)%len];
                }
                stemp[count][j]='\0';
                count++;
            }
        mini=0;
        for(i=0;i<count;i++){//在不同子串中,寻找字典序列最小的串 
            //if(strcmp(stemp[mini],stemp[i])==0)//WA
            if(strcmp(stemp[mini],stemp[i])>0)//AC
                mini=i;
        }
        printf("%s\n",stemp[mini]);
    }
    return 0;
}

总结下他的做法。因为是字典序,所以可以先找到最小的字母s,从最小的字母s开始找寻最小的字符串,然后把所以以s开头的字符串全都保存在二维数组stemp里,然后通过内置函数strcmp找到字典序列最小的串。

相比而言,书上给出的方法更为直接清楚,而他的做法相对而言比较容易想到。

转载于:https://www.cnblogs.com/nymrli/p/9546865.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值