C初学者求助:如何删除文本(txt)中重复的单词
我想的是用俩个数组a,b。先用a数组在for循环先录入文本的一个单词,然后遇到空格后停止,再用b数组对这个单词后的单词一个个录入然后比较,如果一样则将b数组此时所在的位置所移除
[此贴子已经被作者于2022-3-13 15:19编辑过]
/* 如果所有文件都很小,那就全部读到内存中 如果最大需要处理的文件都不算大,那就使用文件读写 如果大部分文件都很大,那就关闭文件读写缓存并分块读到内存,或使用内存映射,但这种情况要考虑块和块的边界 如果单词数目少,直接遍历 如果单词数目中等,使用红黑树、hash表等 如果单词数目很大,那就使用Trie字典树等 最麻烦的就是“单词”的定义,难在一般人不是语法学家,不知道英语中“全部的”单词分割规则。 比如 ming's 如果之前出现过 ming,则 ming's 要全部删除。那么 ming-chao 要不要全部去掉,还是留下 -chao? */ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> struct word { const char* data; size_t length; }; bool found_inbuf( struct word words[], size_t* words_size, const char* search_data, size_t search_length ) { for( size_t i=0; i!=*words_size; ++i ) if( words[i].length==search_length && memcmp(words[i].data,search_data,search_length)==0 ) return true; words[*words_size].data = search_data; words[*words_size].length = search_length; ++*words_size; return false; } void foo( const char* restrict s, char* restrict d ) { struct word words[1000]; size_t words_size = 0; size_t idx_s=0, idx_d=0; for( ; ; ) { // 读取 非单词部分 size_t idx_t = 0; int n = sscanf( s+idx_s, "%*[^A-Za-z]%zn", &idx_t ); if( n == EOF ) break; // 将 非单词部分 原样照搬到目的字符串中 if( idx_t != 0 ) { memcpy( d+idx_d, s+idx_s, idx_t ); idx_d += idx_t; idx_s += idx_t; } // 读取 单词部分 idx_t = 0; n = sscanf( s+idx_s, "%*[A-Za-z]%zn", &idx_t ); if( n == EOF ) break; // 如果 单词 不重复,则将 单词 照搬到目的字符串中 bool bfound = found_inbuf( words, &words_size, s+idx_s, idx_t ); if( !bfound ) { memcpy( d+idx_d, s+idx_s, idx_t ); idx_d += idx_t; } idx_s += idx_t; // 这个 单词 有尾巴(比如 Ming's 中的 's)吗?若有,同上处理 for( ; s[idx_s]>' '; ++idx_s ) { if( !bfound ) d[idx_d++] = s[idx_s]; } } d[idx_d] = '\0'; return; } int main( void ) { const char* s = "Xiao Ming's story: Xiao Ming's father walks into the cafe. Someone shouted, \"Xiao Ming, your father is here.\""; char* d = malloc( strlen(s)+1 ); foo( s, d ); puts( s ); puts( d ); }