鱼C论坛

 找回密码
 立即注册
查看: 2800|回复: 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的字符串。
输出
添加屏蔽词后的结果。
样例输入
[/code]
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...
 
[code]#include<stdio.h>
#include<string.h>
void check(char *s,char *a);//屏蔽信息 
void print(char *a);//打印 
int main(void)
{
        char a[110];
        while(gets(a))//循环输入 
        {
            FILE *fp=fopen("dict.dic","r");
            while(!feof(fp)) 
           {
                        char c=getc(fp);
                        char s[11]={'0'};
                        int i=0;
                        while(c!='\n'&&c!=EOF)
                       {
                                   s[i]=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[i]==s[j])
                {
                        k=i;
                        r=j;
                        while(k<y&&r<x&&a[k]==s[r]) 
                         k++,r++;//判断是否一致        
                } 
                if(r==x&&x!=1)
                {
                        a[k-1]='!';
                        for(int t=2;t<=x;t++)
                            a[k-t]='?';//屏蔽信息 
                }
                else if(r==x&&x==1)
                    a[k-1]='!'; //屏蔽信息                            
        }
        return;
}
void print(char *a)
{
        int x=strlen(a);
        for(int i=0;i<x;)
        {
          if(a[i]!='?'&&a[i]!='!')
           {
            printf("%c",a[i]);
                i++;                  
           }
          else if(a[i]=='?')
           {
            printf("!@#$%^&*");//打印屏蔽字符 
            while(a[i]=='?')
                    i++;     
                }        
           else
           {
            if(a[i-1]=='?'&&i>0)
                    i++; 
                else 
                    printf("!@#$%^&*"),i++;        //单个字母打印                 
           }        
        }
           return;
} 

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-25 16:32:52 | 显示全部楼层
你为什么不自己做?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-25 16:35:34 | 显示全部楼层
好吧,你在自己写了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

我不就是这么做的吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 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[1024]="dsafdsafdsafdasliowjhfo afhafdhfsdjadbs vbdkhdio;oagfeafselfopwfh";
        char temp[10]="af";
        char ch[10]="????????";
        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
请按任意键继续. . .
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

谢谢兄弟,但我其实还是想弄懂自己代码错在哪里。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

可不太行,还是得一个个字母循环,因为观察事例可以发现在在单词中间也可能存在敏感词
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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[Max];
        static char substr[Max]={"888"};//需要替换的字符串
        static char flag[Max]={"<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);
}
想知道小甲鱼最近在做啥?请访问 -> 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码,只是提供一种思路,希望有大佬斧正
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-31 20:54:16 | 显示全部楼层
去看看这个帖子字符串替换
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-10 19:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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