码迷,mamicode.com
首页 > 其他好文 > 详细

QAQ

时间:2019-09-26 21:16:26      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:bre   判断   进一步   单元   过程   解决   mil   bridge   amp   

第一次写项目类代码。

算是用算法解决实际型问题吧。

学会了文件输入输出。

不习惯用C,还是用C++写的。

debug了一节c语言课+晚上看火影的间隙。

HAPPY!

C语言附加题-单词纠错
由于发音相近或者记忆不准确,我们日常生活中常有单词拼写错误的情况发生。而对于自然语言处 理,一般以词为基本处理单元。因此单词纠错是自然语言处理重要的基础算法之一。单词纠错的方 法通常是检测未出现在词典中的单词,然后借助于单词之间的编辑距离来从词典中寻找正确的单 词。
莱文斯坦距离,又称Levenshtein距离,是编辑距离的一种。指两个字串之间,由一个转成 另一个所需的少编辑操作次数。允许的编辑操作包括将一个字符替换成另一个字符,插 入一个字符,删除一个字符。
例如将kitten一字转成sitting: sitten (k→s) sittin (e→i) sitting (→g)
除单词纠错之外,编辑距离还应用于DNA分析、语音辨识、抄袭侦测问题中。
Levenshtein编辑算法基本原理:首先,假设对于字符串A和B,我们使用一个二维数组 distance[1+length of A][1+length of B],其中distance[i][j]的值表示将 A的1到i部分 转换为 B的1到j 部分 需要的最少编辑次数。
所以,在i等于0时,也就是说对于distance[0,j],A的空子串部分到B的前j个元素组成的子串的转 换,需要j此操作。同理可得distance数组的首行和首列为0到i和0到j。 对于剩余的distance[i][j](也就是A1~i元素的子串和B1~j元素的子串的距离),可以由distance[i-1] [j],distance[i][j-1],distance[i-1][j-1]来确定,如果计算A[i]和B[j]相同,取min(distance[i-1][j]+1, distance[i][j-1]+1,distance[i-1][j-1])即可。同理,如果计算A[i]和B[j]不同,就要取 min(distance[i-1][j]+1,distance[i][j-1]+1,distance[i-1][j-1]+1)。 计算出所有distance元素后,我们要求的A到B的编辑距离就是distance[1+length of A][1+length of B]
举个例子,对于luck和 uck两个字符串计算编辑距离,最终的二维数组计算如下(红色为被min()选 中的数值):
字符串ABCD和BCD的距离计算过程:
_ _ u c k
_ 0 1 2 3
l 1 1 2 3
u 2 1 2 3
c 3 2 1 2
k 4 3 2 1
学完C语言的你,是否可以使用编程技巧来对文档中的单词拼写错误进行纠正呢?
题目要求:
读取给定文档(words.txt)和单词表(vocabulary.txt),利用单词表找出文档中拼写错误的单词并将其 改正,把正确的内容存到新的文档之中,命名为words_correct.txt。
为了保证数据的真实性,中间可能夹杂多余空格或者中文等不合格式的信息,中文字符删除,行输 出按给定的模板格式输出;编辑距离相同的词可以取首个出现的词,鼓励加入其它判断进一步筛 选,如是否可通过交换纠正(raed->read)
示例:
0351 grandmother kind/mather/孙子/grandaughter 0707 London England/Endlish/Cambridge developed
要更改为
0351 grandmother kind/mother/grandaughter 0707 London England/English/Cambridge/developed
数据格式:
输出文件每一行分别为:行号 单词1 单词2/单词3/…/单词n

// finished
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<fstream>
using namespace std ;
const int INF = 0x7ffffff ;

inline int read() {
    int k = 0, f = 1 ; char c = getchar() ;
    for( ; !isdigit(c) ; c = getchar())
      if(c == -) f = -1 ;
    for( ; isdigit(c) ; c = getchar())
      k = k*10 + c-0 ;
    return k*f ;
}

char word[5000][20] ;  int tot = 0 ;

inline void in_vocabulary() {
    freopen("vocabulary.txt","r",stdin) ;
    while(1) {
        char c = getchar() ;  if(c == 0) break ;
        int now = 0 ;
        if((c >= a && c <= z) || (c >= A && c <= Z)) {
            tot++ ;
            while((c >= a && c <= z) || (c >= A && c <= Z)) {
                word[tot][now++] = c ; c = getchar() ;
            }
            word[tot][now] = ! ;
        }
    }
    fclose(stdin) ;
/*
    freopen("vocabulary2.txt","r",stdin) ;
    tot = 0 ;
    while(1) {
        char c = getchar() ;  if(c == ‘0‘) break ;
        int now = 0 ;
        if((c >= ‘a‘ && c <= ‘z‘) || (c >= ‘A‘ && c <= ‘Z‘)) {
            tot++ ;
            while((c >= ‘a‘ && c <= ‘z‘) || (c >= ‘A‘ && c <= ‘Z‘)) {
                word[tot][now++] = c ; c = getchar() ;
            }
        }
    }
    fclose(stdin) ;    
    
    for(int i=1;i<=tot;i++) {
        printf("%s\n",word[i]) ;
    }
*/
}

inline int mmin(int a,int b,int c) {
    if(a <= b && a <= c) return a ;
    if(b <= a && b <= c) return b ;
    return c ;
}

inline void in_words() {
    freopen("words.txt","r",stdin) ;
//    freopen("answers.txt","w",stdout) ;
    char c ;  char cc[20] ;
    int dis[20][20] ;   // 动规算单词距离 
    for(int i=0;i<20;i++) dis[0][i] = dis[i][0] = i ;
    while(1) {
        c = getchar() ;  if(c == ]) break ;
        if((c >= a && c <= z) || (c >= A && c <= Z)) {  // 如果读到了单词 
            int tt = 0 ;
            while((c >= a && c <= z) || (c >= A && c <= Z)) cc[tt++] = c, c = getchar() ;
            int minn = INF, ans ;
            for(int x=1;x<=tot;x++) {    // 找距离最短的单词 
                int im = tt ; int jm ; 
                for(jm=0;word[x][jm]!=!;jm++) ; 
                for(int i=1;i<=im;i++) {
                    for(int j=1;j<=jm;j++) {
                        if(word[x][j-1] == cc[i-1]) dis[i][j] = mmin(dis[i-1][j-1],dis[i][j-1]+1,dis[i-1][j]+1) ;
                        else dis[i][j] = mmin(dis[i-1][j-1],dis[i][j-1],dis[i-1][j])+1 ;
                    }
                }
                if(dis[im][jm] < minn) {
                    minn = dis[im][jm] ;
                    ans = x ;
                }
            }
            
//            printf("tot:%d\n",tot) ;
//            printf("\nans:%d\n",ans) ;
//            for(int i=0;i<tt;i++) printf("%c",cc[i]) ; printf("\n") ;
            
            for(int i=0;word[ans][i]!=!;i++) printf("%c",word[ans][i]) ;
        }  printf("%c",c) ;
    }
    fclose(stdin) ;
}

int main() {
    in_vocabulary() ;
/*    
    for(int i=1;i<=tot;i++) {
        printf("%s\n",word[i]) ;
    }    
*/    
    in_words() ;
    return 0 ;
}

还是用了一些小trick的。比如改了输入文件方便判定结束。

属于瑕疵代码。

QAQ

标签:bre   判断   进一步   单元   过程   解决   mil   bridge   amp   

原文地址:https://www.cnblogs.com/zub23333/p/11594010.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!