PTA6-4 按要求移动字符 (5 分)

函数Move_str的功能是:在字符串str中找到ASCII码值最大的字符,将该字符放到首位,其余字符顺序后移。

函数接口定义:

void Move_str ( char *p);

其中 p 是用户传入的参数。

裁判测试程序样例:

#include<stdio.h>
void Move_str ( char *p);
int main()
{
    char str[80];
    gets(str);
    Move_str(str);
    printf("The string after moving:");
    puts(str);
    return 0;
  }


/* 请在这里填写答案 */

输入样例1:

ABCDeFG

输出样例1:

The string after moving:eABCDFG

输入样例2:

ABCDeFGe

输出样例2:

The string after moving:eeABCDFG

 

参考:

1.不开数组,可测试任意多个重复数

void Move_str ( char *p){
//Author:CHENG XIANGBO
    char max=0;
    char *indexStart=p;//记录指针开始地址,保证移动后能获得有效首地址。
    //先找出最大字符
    while(*p!=NULL){
        if(max<=*p)
            max=*p;
        p++;
    }
    char* indexEnd=p;//此时记录有效末地址。
    int flag=0;//flag来记录字符串里,和最大字符max相同的字符的个数。
    //先顺序往后移动,将p移动回首地址。
    while(p!=indexStart){
        if(*(p-1)!=max)
           *p=*(p-1);
        else{
            //如果遇到和max相同的字符,单独考虑。
            flag+=1;//相同个数加一
            char *cnm=p-1;
            //将其覆盖抹除
            while(*cnm!=NULL){
                *cnm=*(cnm+1);
                cnm++;
                }
            }
        p--;
    }
    *p=max;//首地址映射最大值,此时字符串已经有序
    if(flag==1){*indexEnd='\0';}//无重复元素则已经成功
    else{
        //以下代码思路是把相同的字符放字符串最前面,其他元素顺序后移动,具体移动思路同上
        //可优化
        for(int i=0;i<flag-1;i++){//共有flag-1个重复数,须操作flag-1次
            p=indexEnd;
            indexEnd+=1;
            indexStart+=1;
            while(p!=indexStart){
                *(p)=*(p-1);
                p--;
            }
            *p=max;
        }
        *(indexEnd-(flag-1))='\0';//操作结束
    }
}

2.开数组,把while写成for也更方便

void Move_str ( char *p)
{
//Author:OLENCER
//开数组
 int k = 0;
 int max[100];//注意测试大小有十个重复之多,数组开大点
 max[0] = 0;
 for (int i = 0; *(p + i) != '\0';i++){
  if(*(p+max[k])<*(p+i)){
   k = 0;
   max[k] = i;
  }
  else if(*(p+max[k])==*(p+i))
  {
   k++;
   max[k] = i;
  }
 }

 char temp = *(p+max[k]);
    
 for (int c = 0;c<=k;c++)
 {
  for (int j = max[c]; j > 0; j--)
  {
   *(p + j) = *(p + j - 1);
  }
  *p = temp;
 }
}
void Move_str ( char *p){
//Author:Cheng 
//1.找出最大字符
    char max=*p;
    int times=0;
    for(char *maxfind=p;*maxfind;maxfind++){
        if(max<=*maxfind){
            max=*maxfind;
        }
    }
//2.记录最大字符次数
    for(char *maxcnt=p;*maxcnt;maxcnt++){
        if(max==*maxcnt)
            times++;
    }
//3.把不是最大字符的字符放进数组
    char str1[80];
    char *indexStart=p;
    for(int i=0;*indexStart;indexStart++,i++){
        if(*indexStart!=max)
            *(str1+i)=*indexStart;
        else
            i--;
    }
//4.用最大字符冲掉指针指向的前几个元素
    for(;times>0;p++,times--){
        *p=max;
    }
//5.剩下的由str1数组内容填写冲刷
    for(int i=0;*p;p++,i++){
        *p=*(str1+i);
    }
}

 

                                                                                                              @FROM:CAFUC

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值