例题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找到字典序列最小的串。
相比而言,书上给出的方法更为直接清楚,而他的做法相对而言比较容易想到。