nameisnothing 发表于 2020-3-25 15:39:36

一道oj题的思路

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

样例输出
如果屏蔽词库如下:
is
good
are
the
ha ha
some
get
has
more
bad
则输出:

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

#include<stdio.h>
#include<string.h>
void check(char *s,char *a);//屏蔽信息
void print(char *a);//打印
int main(void)
{
        char a;
        while(gets(a))//循环输入
        {
          FILE *fp=fopen("dict.dic","r");
            while(!feof(fp))
           {
                        char c=getc(fp);
                        char s={'0'};
                        int i=0;
                        while(c!='\n'&&c!=EOF)
                       {
                                   s=c;
                                   i++;
                                   c=getc(fp);//读取屏蔽词
                  }
                             check(s,a);
          }
      print(a);
                printf("\n");       
        }
        return 0;
}
void check(char *s,char *a)
{
        int x=strlen(s);
        int y=strlen(a);
        int i,j=0,k=0,r=0;
        for(i=0;i<y;i++)
        {
                if(a==s)
                {
                        k=i;
                        r=j;
                        while(k<y&&r<x&&a==s)
                         k++,r++;//判断是否一致       
                }
                if(r==x&&x!=1)
                {
                        a='!';
                        for(int t=2;t<=x;t++)
                          a='?';//屏蔽信息
                }
                else if(r==x&&x==1)
                  a='!'; //屏蔽信息                          
        }
        return;
}
void print(char *a)
{
        int x=strlen(a);
        for(int i=0;i<x;)
        {
          if(a!='?'&&a!='!')
           {
          printf("%c",a);
                i++;                 
           }
          else if(a=='?')
           {
          printf("!@#$%^&*");//打印屏蔽字符
          while(a=='?')
                  i++;   
                }       
           else
           {
          if(a=='?'&&i>0)
                  i++;
                else
                  printf("!@#$%^&*"),i++;        //单个字母打印              
           }       
        }
           return;
}

人造人 发表于 2020-3-25 16:32:52

你为什么不自己做?

人造人 发表于 2020-3-25 16:35:34

好吧,你在自己写了

人造人 发表于 2020-3-25 16:42:05

给你个思路,先把dict.dic文件中的所有单词都读取出来,保存到数组
然后对字符串进行扫描,匹配到的单词进行替换,不匹配就输出

nameisnothing 发表于 2020-3-25 16:59:22

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

我不就是这么做的吗

Cool_Breeze 发表于 2020-3-25 17:12:42

strcmp 比较字符串
将关键字符串和输入字符串比较(可以百度在一串字符中搜索指定指定字符串)。如果有记录位置,替换。我想应该可以的!

nameisnothing 发表于 2020-3-25 18:12:15

我现在想知道我这段代码具体错在哪里,如果错了,应该怎么改,毕竟每个人思路不同,太多了,不可能一个思路写一次。

Cool_Breeze 发表于 2020-3-25 18:34:42

给你个思路,你看看行不行!

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

int findstr(char *s,char *f,char *c);
int main(void)
{
        char arr="dsafdsafdsafdasliowjhfo afhafdhfsdjadbs vbdkhdio;oagfeafselfopwfh";
        char temp="af";
        char ch="????????";
        findstr(arr,temp,ch);
    return 0;
}
//采用类似字符串拼接方式
int findstr(char *s,char *f,char *c)
{
        //获取字符串长度
        size_t s_len=strlen(s);
        size_t f_len=strlen(f);
        size_t c_len=strlen(c);
       
        if (s_len < f_len ) return -1;//如果输入字符串比约束字符串短就退出
        register int i=0,j=0;
        for (;i<s_len-f_len;i++)
                if ( ! strncmp(s+i,f,f_len) )
                {
                        *(s+i)='\0';
                        printf("%s%s",s+j,c);
                        j=i+f_len;
                        i=i+f_len-1;
                }
        printf("%s",s+j);//打印剩余字符串或者原字符串;
        return 0;
}
ds????????ds????????ds????????dasliowjhfo ????????h????????dhfsdjadbs vbdkhdio;oagfe????????selfopwfh
--------------------------------
Process exited after 0.01573 seconds with return value 0
请按任意键继续. . .

nameisnothing 发表于 2020-3-25 19:01:28

Cool_Breeze 发表于 2020-3-25 18:34
给你个思路,你看看行不行!

谢谢兄弟,但我其实还是想弄懂自己代码错在哪里。

shimmermao 发表于 2020-3-27 18:35:08

Cool_Breeze 发表于 2020-3-25 17:12
strcmp 比较字符串
将关键字符串和输入字符串比较(可以百度在一串字符中搜索指定指定字符串)。如果有记录 ...

可不太行,还是得一个个字母循环,因为观察事例可以发现在在单词中间也可能存在敏感词

Cool_Breeze 发表于 2020-3-31 16:34:11

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

FILE* filepointer(const char *file,const char *mode);
void insert_str(char* str,char* flag,size_t sl,size_t fn);
void replace_gtr_str(char* str,char* flag,size_t sl,size_t fl);
void replace_lss_str(char* str,char* flag,size_t subl,size_t fl);
void replace_equ_str(char* str,char* flag,size_t fl);

//字符串大小
#define Max 1024

int main(int argc,char **argv)
{
      FILE* fp=filepointer("test.txt","rb");
      FILE* fpo=filepointer("result.txt","wb");      
      static char str;
      static char substr={"888"};//需要替换的字符串
      static char flag={"<A>"};//替换后的字符串
      char *p=str;
      while (fgets(str,Max,fp))
      {
                p=str;
                for (;;)
                {
                        p=strstr(p,substr);
                        if (p == NULL) break;
                        if (strlen(substr) < strlen(flag)) replace_lss_str(p,flag,strlen(substr),strlen(flag));
                        else if (strlen(substr) > strlen(flag)) replace_gtr_str(p,flag,strlen(substr),strlen(flag));
                        else if (strlen(substr) == strlen(flag)) replace_equ_str(p,flag,strlen(flag));
                }
                fprintf(fpo,"%s",str);
      }
      fclose(fp);
      fclose(fpo);
    return 0;
}

FILE* filepointer(const char *file,const char *mode)
{
      FILE *fp;
      if (!(fp = fopen(file,mode)))
      {
                printf("open fail! [%s]:%s\n",file,strerror(errno));
                exit(EXIT_FAILURE);
      }
      return fp;
}
/*
      在字符串开始插入指定字符串
      str原字符串的起点
      flag 指定字符串
      sl   原字符串长度
      fl   指定字符串长度
*/
void insert_str(char* str,char* flag,size_t sl,size_t fl)
{
      memmove(str+fl,str,sl+1);//+1存放结束符'\0'
      memmove(str,flag,fl);
}
/*
      被替换字符串长度大于替换字符字符串长度
      explanation:
      str=abcd,flag=abc
      
      str原字符串的起点
      flag 替换的字符串
      sl   被替换字符长度
      fl   替换字符串长度
*/
void replace_gtr_str(char* str,char* flag,size_t sl,size_t fl)
{
      memmove(str+fl,str+sl,sl+1);
      memmove(str,flag,fl);
}
/*
      被替换字符长度小于替换字符串长度
      删除被替换字符串
      explanation:
      str=abc,flag=abcd
      
      str原字符串的起点
      flag 替换的字符串
      subl 被替换字符长度
      fl   替换字符串长度
*/
void replace_lss_str(char* str,char* flag,size_t subl,size_t fl)
{
      register size_t temp=strlen(str)-subl;//剩余字符串长度
      memmove(str+fl,str+subl,temp+1);
      memmove(str,flag,fl);
}
/*
      被替换字符串与指定字符串相等
      explanation:
      str=abc,flag=abc
      
      str原字符串的起点
      flag 替换的字符串
      fl   替换字符长度
         
*/
void replace_equ_str(char* str,char* flag,size_t fl)
{
      memmove(str,flag,fl);
}

luoruitao 发表于 2020-3-31 17:58:47

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

Cool_Breeze 发表于 2020-3-31 20:54:16

去看看这个帖子字符串替换

Given2001 发表于 2020-4-1 09:19:16

本帖最后由 Given2001 于 2020-4-1 13:21 编辑

大概找到问题所在了
你的思路大概是检查原字符串,然后把找到的和谐词替换成 !??? 的形式,这样做是不安全的,要是原文就存在感叹号和问号就会错误屏蔽。
具体看我的测试图
页: [1]
查看完整版本: 一道oj题的思路