题解 | #单词倒排#

单词倒排

http://www.nowcoder.com/practice/81544a4989df4109b33c2d65037c5836

搞点思路:

字符串中含有多种无用字符时,宜采用结束符作为标志,按字符输入。

收入的最后一个索引编号则为字符串长度-1.

但因为循环需要的i++补充了1,所以可将i之终值作为字符串长度

只有一类或者几类有用字符时,可用if筛选有用字符存入新数组。

当有按照原格式需求时(例:按照原间隔符间隔字符串),可在扫描字符串序列时候记录格式信息。 (此题由于只需要清洗其余间隔符,所以只反其道而行之记录了最后一个有用字符的索引,将所有连续间隔符都与前一个有用字符关联)(如果是需要原格式的情况,可以直接记录无用字符的索引。)

得到的间隔符数组含有重复项,因此需要再一次清洗。间隔符序列中含有相同字母索引的项全部放入新的序列,将间隔符保存的内容(字母被间隔处索引)变为新序列的索引(置位1),每次有相同索引出现均置位1,可以合多为一。

PS:因为头尾间隔符不需要,所以直接将其用一个if语句剔除。

新序列记录了字母序列索引信息,所以可以将新序列作为字母序列的信号位,对字母序列进行单个间隔符的插入,达到剔除多个间隔符的目的。

现在的序列只含有有用字符和相应断开位置含有的一个间隔符。


以下参考了一道原来做过的逆序题目,参考了一位大佬的处理程序。

因为要逆序句子而不逆序单词,可以通过格式化输出直接将这个处理后的序列按位置取出。

倒序访问序列,当访问到倒数第一个空格时候,访问空格下一个位置的地址,此时如果按照%s的格式输出,会直接输出到结束符处,实现了最后一个单词换到第一个位置输出。再输出一个空格实现分隔。然后将空格换为结束符,丢弃已经输出过的部分。再次进行循环,倒叙开始,此时访问到原倒数第二个间隔符,今最后一个间隔符,输出范围是倒数第二个间隔符到上一次循环添加的结束符位置。其余依此类推。

当到最后一个空格时,还有一个原序列的首位单词没输出,所以要记得再输出一次首位单词。

此时格式化输出可以直接写形参,默认访问第一个地址。范围到结束符结束。

#include<stdio.h>
#include<string.h>

char in,input[10000],asb[10000],forward[10000],backword[10000];
int i,j=0,k=0,flag=0,len,mark[1000],structure,ind,inde[1000],true_len;

int main()
{
    while(1)
    {
        
        if(in!='\n')
        
        {
        scanf("%c",&in);//按字符输入
        input[i]=in;
        i++;
        }
        else 
            break;
    }
    len = i;
    
    for(i=0;i<len;i++)
    {
        
        if((input[i]>='A'&&input[i]<='Z')||(input[i]>='a'&&input[i]<='z'))
        {
            asb[j]=input[i];//记录字母
            
            j++;//字母之索引
            
        }
        else
        {
        mark[k]=j-1;//记录分隔符位置,但没解决多个分隔符问题
        k++;//分隔符之索引
        }
    }
    structure=j;//字母总数
    ind=k;//间隔符总数
    
    memset(inde,0,sizeof(int)*1000);//初始化索引数组,全置零
    for(i=0;i<ind;i++)//有间隔的索引置位;去除索引重复的间隔符,只留下一个;去头尾间隔符(如果有)
    {
        if((mark[i]!=(-1))&&(mark[i]!=(structure-1)))//记录间隔符在字母序列之中的位置(哪个字母后)     
        {
            inde[mark[i]]=1; //多次重复只记录一个,该位置1,将内容变为索引,头尾分隔符去除。
        }      
    }
    j=0;
    
    for(i=0;i<structure;i++)//在字母序列的间隔处放置一空格
    {
      forward[j]=asb[i]; 
      if(inde[i]==1)//通过分隔符索引位置在序列中插入空格
      {
         forward[j+1]=' ';
          j++;
      }  
     j++;   
    }
    
    true_len=j;//字母及一间隔符长度
    
    for(i=strlen(forward)-1;i>=0;i--)//逆序
    {
        if(forward[i]==' ')
        {
            printf("%s",&forward[i+1]);//从空格的下一位开始输出,利用printf的格式化控制,格式控制为%s时,输出到结束符为止。
           forward[i]='\0';//输出后将空格写为结束符,控制下一次printf的输出范围
           printf(" ");//输出空格
        }
        
    }
   printf("%s",forward);//输出最后一个单词
    
    
    
    
}
全部评论

相关推荐

昨天 14:22
门头沟学院 Java
大厂 测开 24*16离家近的事业编(大概只有大厂的1/4) 硕士
点赞 评论 收藏
分享
点赞 评论 收藏
分享
牛客963010790号:为什么还要收藏
点赞 评论 收藏
分享
联通 技术人员 总包不低于12
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务