鱼C论坛

 找回密码
 立即注册
查看: 3460|回复: 13

一道oj题的思路

[复制链接]
发表于 2020-3-25 15:39:36 | 显示全部楼层 |阅读模式
10鱼币
这道题我样例过了,但是答案错误。我不知道会不会是我思路有问题。
题目描述
互联网中存在许多的不和谐词汇,在我们浏览互联网的时候,搜索引擎经常会出现提示信息“根据相关法律法规和政策,部分搜索结果未予显示”。小王同学也想制作一个自己的屏蔽词库,这样他就可以将自己不喜欢的词汇从文件中换成别的字符了。屏蔽词库是一个ASCII码文件,这个文件中只含有单词,每个单词占一行,每个单词中只可能有大小写字母与空格。题目中和谐词库的文件名为dict.dic。(屏蔽词库中每个词汇长度小于10,屏蔽词汇个数不超过10.)
你的任务是将输入中的所有和谐词库中的词语全部替换成“!@#$%^&*”(按住键盘shift和数字1至8),然后输出。这里要注意,如果一个词语中包含屏蔽词汇,那么只将屏蔽词汇替换,例如“hehasAAA”被处理后将得到“he!@#$%^&*AAA”,注意屏蔽词汇区分大小写,即aaa与AAA是两个不同的单词,为了使问题简化,屏蔽词汇中不会出现互相包含的情况,如“xabcx”与“abc”不会同时出现在同一个屏蔽词库中。由于小王同学很不擅长文件操作,所以他希望你能帮他制作这个屏蔽词汇程序。
输入
若干长度小于100的字符串。
输出
添加屏蔽词后的结果。
样例输入
  1. [/code]
  2. The night falls gently. And you are not here. I missing you more and more and I start getting worried as
  3. I stare at the door just waiting for you to surprise me with your arrival at any moment.
  4. Sweet delusion... you are so far away right now that all I can ask for is that time moves faster...

  5. 样例输出
  6. 如果屏蔽词库如下:
  7. is
  8. good
  9. are
  10. the
  11. ha ha
  12. some
  13. get
  14. has
  15. more
  16. bad
  17. 则输出:

  18. The night falls gently. And you !@#$%^&* not here. I m!@#$%^&*sing you !@#$%^&* and !@#$%^&* and I start !@#$%^&*ting worried as
  19. I st!@#$%^&* at !@#$%^&* door just waiting for you to surpr!@#$%^&*e me with your arrival at any moment.
  20. Sweet delusion... you !@#$%^&* so far away right now that all I can ask for !@#$%^&* that time moves faster...

  21. [code]#include<stdio.h>
  22. #include<string.h>
  23. void check(char *s,char *a);//屏蔽信息
  24. void print(char *a);//打印
  25. int main(void)
  26. {
  27.         char a[110];
  28.         while(gets(a))//循环输入
  29.         {
  30.             FILE *fp=fopen("dict.dic","r");
  31.             while(!feof(fp))
  32.            {
  33.                         char c=getc(fp);
  34.                         char s[11]={'0'};
  35.                         int i=0;
  36.                         while(c!='\n'&&c!=EOF)
  37.                        {
  38.                                    s[i]=c;
  39.                                    i++;  
  40.                                    c=getc(fp);//读取屏蔽词
  41.                     }
  42.                                check(s,a);
  43.             }
  44.         print(a);
  45.                 printf("\n");       
  46.         }
  47.         return 0;
  48. }
  49. void check(char *s,char *a)
  50. {
  51.         int x=strlen(s);
  52.         int y=strlen(a);
  53.         int i,j=0,k=0,r=0;
  54.         for(i=0;i<y;i++)
  55.         {
  56.                 if(a[i]==s[j])
  57.                 {
  58.                         k=i;
  59.                         r=j;
  60.                         while(k<y&&r<x&&a[k]==s[r])
  61.                          k++,r++;//判断是否一致       
  62.                 }
  63.                 if(r==x&&x!=1)
  64.                 {
  65.                         a[k-1]='!';
  66.                         for(int t=2;t<=x;t++)
  67.                             a[k-t]='?';//屏蔽信息
  68.                 }
  69.                 else if(r==x&&x==1)
  70.                     a[k-1]='!'; //屏蔽信息                            
  71.         }
  72.         return;
  73. }
  74. void print(char *a)
  75. {
  76.         int x=strlen(a);
  77.         for(int i=0;i<x;)
  78.         {
  79.           if(a[i]!='?'&&a[i]!='!')
  80.            {
  81.             printf("%c",a[i]);
  82.                 i++;                 
  83.            }
  84.           else if(a[i]=='?')
  85.            {
  86.             printf("!@#$%^&*");//打印屏蔽字符
  87.             while(a[i]=='?')
  88.                     i++;     
  89.                 }       
  90.            else
  91.            {
  92.             if(a[i-1]=='?'&&i>0)
  93.                     i++;
  94.                 else
  95.                     printf("!@#$%^&*"),i++;        //单个字母打印                
  96.            }       
  97.         }
  98.            return;
  99. }
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-25 16:32:52 | 显示全部楼层
你为什么不自己做?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-25 16:35:34 | 显示全部楼层
好吧,你在自己写了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-25 16:42:05 | 显示全部楼层
给你个思路,先把dict.dic文件中的所有单词都读取出来,保存到数组
然后对字符串进行扫描,匹配到的单词进行替换,不匹配就输出
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-25 16:59:22 | 显示全部楼层
人造人 发表于 2020-3-25 16:42
给你个思路,先把dict.dic文件中的所有单词都读取出来,保存到数组
然后对字符串进行扫描,匹配到的单词进 ...

我不就是这么做的吗
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-25 17:12:42 | 显示全部楼层
strcmp 比较字符串
将关键字符串和输入字符串比较(可以百度在一串字符中搜索指定指定字符串)。如果有记录位置,替换。我想应该可以的!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-25 18:12:15 | 显示全部楼层
我现在想知道我这段代码具体错在哪里,如果错了,应该怎么改,毕竟每个人思路不同,太多了,不可能一个思路写一次。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-25 18:34:42 | 显示全部楼层
给你个思路,你看看行不行!

  1. #include <stdio.h>
  2. #include <stddef.h>
  3. #include <string.h>

  4. int findstr(char *s,char *f,char *c);
  5. int main(void)
  6. {
  7.         char arr[1024]="dsafdsafdsafdasliowjhfo afhafdhfsdjadbs vbdkhdio;oagfeafselfopwfh";
  8.         char temp[10]="af";
  9.         char ch[10]="????????";
  10.         findstr(arr,temp,ch);
  11.     return 0;
  12. }
  13. //采用类似字符串拼接方式
  14. int findstr(char *s,char *f,char *c)
  15. {
  16.         //获取字符串长度
  17.         size_t s_len=strlen(s);
  18.         size_t f_len=strlen(f);
  19.         size_t c_len=strlen(c);
  20.        
  21.         if (s_len < f_len ) return -1;//如果输入字符串比约束字符串短就退出
  22.         register int i=0,j=0;
  23.         for (;i<s_len-f_len;i++)
  24.                 if ( ! strncmp(s+i,f,f_len) )
  25.                 {
  26.                         *(s+i)='\0';
  27.                         printf("%s%s",s+j,c);
  28.                         j=i+f_len;
  29.                         i=i+f_len-1;
  30.                 }
  31.         printf("%s",s+j);//打印剩余字符串或者原字符串;
  32.         return 0;
  33. }
复制代码
  1. ds????????ds????????ds????????dasliowjhfo ????????h????????dhfsdjadbs vbdkhdio;oagfe????????selfopwfh
  2. --------------------------------
  3. Process exited after 0.01573 seconds with return value 0
  4. 请按任意键继续. . .
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-25 19:01:28 | 显示全部楼层
Cool_Breeze 发表于 2020-3-25 18:34
给你个思路,你看看行不行!

谢谢兄弟,但我其实还是想弄懂自己代码错在哪里。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-27 18:35:08 | 显示全部楼层
Cool_Breeze 发表于 2020-3-25 17:12
strcmp 比较字符串
将关键字符串和输入字符串比较(可以百度在一串字符中搜索指定指定字符串)。如果有记录 ...

可不太行,还是得一个个字母循环,因为观察事例可以发现在在单词中间也可能存在敏感词
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-31 16:34:11 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <string.h>

  5. FILE* filepointer(const char *file,const char *mode);
  6. void insert_str(char* str,char* flag,size_t sl,size_t fn);
  7. void replace_gtr_str(char* str,char* flag,size_t sl,size_t fl);
  8. void replace_lss_str(char* str,char* flag,size_t subl,size_t fl);
  9. void replace_equ_str(char* str,char* flag,size_t fl);

  10. //字符串大小
  11. #define Max 1024

  12. int main(int argc,char **argv)
  13. {
  14.         FILE* fp=filepointer("test.txt","rb");
  15.         FILE* fpo=filepointer("result.txt","wb");        
  16.         static char str[Max];
  17.         static char substr[Max]={"888"};//需要替换的字符串
  18.         static char flag[Max]={"<A>"};//替换后的字符串
  19.         char *p=str;
  20.         while (fgets(str,Max,fp))
  21.         {
  22.                 p=str;
  23.                 for (;;)
  24.                 {
  25.                         p=strstr(p,substr);
  26.                         if (p == NULL) break;
  27.                         if (strlen(substr) < strlen(flag)) replace_lss_str(p,flag,strlen(substr),strlen(flag));
  28.                         else if (strlen(substr) > strlen(flag)) replace_gtr_str(p,flag,strlen(substr),strlen(flag));
  29.                         else if (strlen(substr) == strlen(flag)) replace_equ_str(p,flag,strlen(flag));
  30.                 }
  31.                 fprintf(fpo,"%s",str);
  32.         }
  33.         fclose(fp);
  34.         fclose(fpo);
  35.     return 0;
  36. }

  37. FILE* filepointer(const char *file,const char *mode)
  38. {
  39.         FILE *fp;
  40.         if (!(fp = fopen(file,mode)))
  41.         {
  42.                 printf("open fail! [%s]:%s\n",file,strerror(errno));
  43.                 exit(EXIT_FAILURE);
  44.         }
  45.         return fp;
  46. }
  47. /*
  48.         在字符串开始插入指定字符串
  49.         str  原字符串的起点
  50.         flag 指定字符串
  51.         sl   原字符串长度
  52.         fl   指定字符串长度
  53. */
  54. void insert_str(char* str,char* flag,size_t sl,size_t fl)
  55. {
  56.         memmove(str+fl,str,sl+1);//+1存放结束符'\0'
  57.         memmove(str,flag,fl);
  58. }
  59. /*
  60.         被替换字符串长度大于替换字符字符串长度
  61.         explanation:
  62.         str=abcd,flag=abc
  63.         
  64.         str  原字符串的起点
  65.         flag 替换的字符串
  66.         sl   被替换字符长度
  67.         fl   替换字符串长度
  68. */
  69. void replace_gtr_str(char* str,char* flag,size_t sl,size_t fl)
  70. {
  71.         memmove(str+fl,str+sl,sl+1);
  72.         memmove(str,flag,fl);
  73. }
  74. /*
  75.         被替换字符长度小于替换字符串长度
  76.         删除被替换字符串
  77.         explanation:
  78.         str=abc,flag=abcd
  79.         
  80.         str  原字符串的起点
  81.         flag 替换的字符串
  82.         subl 被替换字符长度
  83.         fl   替换字符串长度
  84. */
  85. void replace_lss_str(char* str,char* flag,size_t subl,size_t fl)
  86. {
  87.         register size_t temp=strlen(str)-subl;//剩余字符串长度
  88.         memmove(str+fl,str+subl,temp+1);
  89.         memmove(str,flag,fl);
  90. }
  91. /*
  92.         被替换字符串与指定字符串相等
  93.         explanation:
  94.         str=abc,flag=abc
  95.         
  96.         str  原字符串的起点
  97.         flag 替换的字符串
  98.         fl   替换字符长度
  99.          
  100. */
  101. void replace_equ_str(char* str,char* flag,size_t fl)
  102. {
  103.         memmove(str,flag,fl);
  104. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-31 17:58:47 | 显示全部楼层
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
        char huan[11];
        char *words[11];
        char pingbi[]={"!@#$%^&*"};
        int len,i=0,count,j,k,flag=0,o;
        int num[10];
        FILE *fp=fopen("dict.dic","r");
        while((fgets(huan,10,fp))!=NULL)
        {
                num[i]=strlen(huan);
                words[i]=(char *)malloc(len+1);
                strcpy(words[i],huan);
                i++;
        }
        count=i;                                                                        //用来记录有多少屏蔽单词
        if(count>1)
        {
                for(i=0;i<count-1;i++)
                {
                        num[i]--;
                        for(j=0;j<num[i];j++)
                        {
                                huan[j]=words[i][j];
                        }
                        huan[j]='\0';
                        strcpy(words[i],huan);                                //此处调整字符数组中再字母后有莫名其妙字符的影响并把回车去掉
                }
        }
        /*for(i=0;i<count;i++)
        {
                puts(words[i]);
                printf("%d\n",num[i]);       
        }*/
        i=0;
        char chuli[111];
        while((gets(chuli))!=NULL)                                        //处理输入的字符
        {
                while(chuli[i]!='\0')                                        //处理一串字符串中的每一个字符
                {
                        for(j=0;j<count&&flag==0;j++)                //对应每一个屏蔽词
                        {
                                for(k=0;k<num[j];k++)                         
                                {
                                        huan[k]=chuli[i+k];                        //提取和屏蔽词字符数一样的部分复制在huan字符数组里
                                }
                                huan[k]='\0';
                                if(strcmp(huan,words[j])==0)        //如果字符对应上,说明是相同的
                                {
                                        flag=1;
                                        printf("%s",pingbi);
                                        i+=num[j]-1;
                                }
                        }
                        if(flag==0)
                        putchar(chuli[i]);                                        //如果没有对应字符,直接输出
                        i++;
                        flag=0;
                }
                printf("\n");
                i=0;
        }
        return 0;
}
       
注:非ac码,只是提供一种思路,希望有大佬斧正
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-31 20:54:16 | 显示全部楼层
去看看这个帖子字符串替换
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-4-1 09:19:16 | 显示全部楼层
本帖最后由 Given2001 于 2020-4-1 13:21 编辑

大概找到问题所在了
你的思路大概是检查原字符串,然后把找到的和谐词替换成 !??? 的形式,这样做是不安全的,要是原文就存在感叹号和问号就会错误屏蔽。
具体看我的测试图
QQ截图20200401091209.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-1 21:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表