版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 课程名称 Linux下的标准C 设计题目 英汉电子辞典 项目组长 邢美慧 组 员 丁宝 陈飞 郭宗良 欧阳晨阳 指导教师 王建立 2014 年 8 月目录一、设计时间1二、设计目的1三、需求分析13.1 单词查询13.2 建立索引,并使用索引进行单词查询13.3 用户添加新词1四、系统分析24.1 功能分析24.1.1 系统功能分析24.1.2 文本查找功能分析24.1.3 建立索引功能分析24.1.4 索引查找功能分析24.1.5 添加新词功能分析34.2 概要设计34.2.1 系统功能结构图34.2.2 文本查找功能图44.2.3 建立索引功能图54.2.4 索引查找功能图64.2.5
2、添加新词功能图74.3 各模块细化分析84.3.1 内存存储结构 - 哈希表的实现84.3.2 二进制索引文件构造图94.3.3 文本查询细化分析94.3.4 建立索引文件细化分析124.3.5 索引查询细化分析164.3.6 添加新词细化分析19五、系统设计205.1 硬件环境215.2 选择语言215.3 功能关系215.4 框架设计225.5 详细设计235.5.1 抽象数据类型235.5.2 函数接口声明23六、 编码276.1 模块1代码286.2 模块2代码286.3 模块3代码366.4 模块4代码396.5 主函数代码41七、 测试417.1 单元测试427.1.1 模块1测试
3、427.1.2 模块2测试437.1.3 模块3测试447.1.4 模块4测试467.2 集成测试47八、使用说明书48九、维护49一、设计时间2014年8月18日-2014年8月25日二、设计目的通过本次课程设计,熟悉C语言的程序设计与技巧,进一步提高编写程序,分析程序及上机操作,调试程序的能力,提高动手操作能力及分析问题和解决问题的能力三、需求分析3.1 单词查询给定文本文件“dict.txt”,该文件用于存储词库。词库为“英-汉”,“汉-英”双语词典,每个单词和其解释的格式固定,如下所示:#单词Trans:解释1解释2解释n每个新单词由“#”开头,解释之间使用“”隔开。一个词可能有多个解
4、释,解释均存储在一行里,行首固定以“Trans:”开头。下面是一个典型的例子:#abyssinianTrans:a. 阿比西尼亚的n. 阿比西尼亚人;依索比亚人该词有两个解释,一个是“a. 阿比西尼亚的”;另一个是“n. 阿比西尼亚人;依索比亚人”。要求编写程序将词库文件读取到内存中,接受用户输入的单词,在字典中查找单词,并且将解释输出到屏幕上。用户可以反复输入,直到用户输入“exit”字典程序退出。程序执行格式如下所示:./app text-text表示使用文本词库进行单词查找。3.2 建立索引,并使用索引进行单词查询要求建立二进制索引,索引格式如下图所示。将文本文件“dict.txt”文件
5、转换为上图所示索引文件“dict.dat”,使用索引文件实现单词查找。程序执行格式如下:./app index-index表示使用文本词库dict.txt建立二进制索引词库dict.dat./app bin-bin表示使用二进制索引词库进行单词查找。3.3 用户添加新词用户添加的新词存放在指定文件中。如果待查单词在词库中找不到,则使用用户提供的词库。用户的词库使用文本形式保存,便于用户修改。程序执行格式图1-1所示。./app 词库选择选项 -f 用户词库文件名词库选项为-test1,或者-test2,表示使用文本词库或者二进制索引词库。-f为固定参数,用来指定用户词库文件名。四、系统分析4.
6、1 功能分析4.1.1 系统功能分析该项目包含4个主要功能:使用文本文件进行单词查询;使用文本文件生成二进制索引文件;使用二进制索引文件进行单词查询;用户添加新词; 当用户输入./app -text 执行功能1; 当用户输入./app -index 执行功能2; 当用户输入./app -bin 执行功能3; 当用户输入./app -insert 执行功能4;4.1.2 文本查找功能分析当用户从终端输入./app -text后进入该功能模块,系统会提示用户输入要查询的英文单词,当用户键入待查单词后,程序会先从dict.txt文件中查询该单词,若查到,即在终端显示解释;若未查到,再到自定义文本my
7、_dict.txt中查询,若查到,即在终端显示解释;若未查到,则在终端提示“此单词未找到”。用户可以反复查询,直到键入Exit结束整个程序。4.1.3 建立索引功能分析当用户从终端输入./app -index后进入该功能模块,系统会生成一个新的二进制文件dict.dat,若原已存在,将会被覆盖,程序将文本文件dict.txt中的内容写进该二进制文件,并且生成一个目录写进该二进制文件,在建立完成后将会提示“建立成功”4.1.4 索引查找功能分析当用户从终端输入./app -bin后进入该功能模块,系统会提示用户输入要查询的英文单词,当用户键入待查单词后,程序会从二进制索引文件dict.dat中查
8、询该单词,若查到,即在终端显示解释;若未查到,则在终端提示“此单词未找到”。用户可以反复查询,直到键入Exit结束该程序。4.1.5 添加新词功能分析当用户从终端输入./app -insert后进入该功能模块,系统会提示用户要插入的英文单词,当用户键入待插单词后,程序会先在标准文本和自定义文本两个文件中查找该单词,若查到,则提示“该单词已存在,不能添加”;若未查到,则提示用户输入待插单词的所有解释,将单词及解释写进自定义文本my_dict.txt中4.2 概要设计4.2.1 系统功能结构图图-系统功能4.2.2 文本查找功能图图 module1.ddd4.2.3 建立索引功能图图 module
9、2.ddd4.2.4 索引查找功能图图 module3.ddd4.2.5 添加新词功能图图 module4.ddd4.3 各模块细化分析4.3.1 内存存储结构 - 哈希表的实现分析:1.将同一个解释的长度和内容组成一个结点; 2.将同一个单词的所有解释存储在一条链表上; 3.将一个单词的长度、内容、解释个数及解释链表的头指针组成一个结点; 4.将所有单词首字母相同的单词结点存储在一条链表上; 5.声明一个结构体数组,数组元素分别存放26个英文字母和26条单词链表 的头指针图 哈希表存储结构 好处:1.只加载英文部分,加载速度很快 2.锁定在特定链表中查询,查找速度很快4.3.2 二进制索引文
10、件构造图4.3.3 文本查询细化分析4.3.3.1 加载内存图 load_memory_text.ddd4.3.3.2 清除字符串后的空格图 clear_space.ddd4.3.3.3 在哈希表中查询单词图search_word_text.ddd4.3.3.4 在自定义文本中查询单词图 search_word_mytext.ddd4.3.4 建立索引文件细化分析4.3.4.1 建立二进制索引文件图 build_dat_index.ddd4.3.4.2 将文本内容写入二进制索引文件图 write_content_dat_index.ddd4.3.4.3 将目录写进二进制索引文件图 write_
11、list_dat_index.ddd4.3.4.4 将目录开始的索引写进二进制索引文件 图 write_listkey_dat_index.ddd4.3.4.5 将单词个数写进二进制索引文件 图 write_wordnum_dat_index.ddd4.3.5 索引查询细化分析4.3.5.1 加载内存 图 Load_memory_bin.ddd4.3.5.2 在目录中查询单词图 search_index_bin.ddd4.3.5.3 通过索引在正文中查询单词图 search_word_with_index_bin.ddd4.3.6 添加新词细化分析4.3.6.1 将单词及解释写进自定义文本中图
12、 write_word_mytext_insert.ddd五、系统设计5.1 硬件环境支持Linux下的gcc编译环境5.2 选择语言C语言5.3 功能关系5.4 框架设计5.5 详细设计5.5.1 抽象数据类型typedef struct trans trans_t;typedef struct word word_t;typedef struct first first_t;typedef struct array array_t;typedef struct index index_t;typedef struct indexdata index_data;/*1.存放解释的结构体*/s
13、truct transint trans_length;char trans_nameSIZE;trans_t *next;typedef trans_t *trans_p;/*2.存放单词的结构体*/struct wordint word_length;char word_nameSIZE;int trans_num;trans_p head;word_t *next;typedef word_t *word_p;/*3.存放哈希数组元素的结构体*/struct firstchar ch;word_p next;typedef first_t *first_p;/*4.存放指针哈希数组的结构
14、体*/struct arrayfirst_p hash26;typedef array_t *array_p; /*5.存放目录的结构体*/struct indexchar word_nameSIZE;long position;index_t *next;typedef index_t *index_p;/*6.存放目录数据域的结构体*/struct indexdatachar word_nameSIZE;long position;5.5.2 函数接口声明5.5.2.1 模块1函数原型:void module1(void)函数参数:void函数返回值类型:void函数功能:使用文本词库进行
15、单词查询函数原型:array_p load_memory_text(char *,array_p)函数参数:char *,array_p函数返回值类型:array_p函数功能:文本词库加载到内存中,采用哈希表结构函数原型:word_p search_word_text(array_p,char *)函数参数:array_p,char *函数返回值类型:word_p函数功能:哈希表中查找单词函数原型:word_p search_word_mytext(char *,char *)函数参数:char *,char *函数返回值类型:word_p函数功能:自定义文本词库中查找单词函数原型:trans
16、_p create_trans_node_text(char *)函数参数:char *函数返回值类型:trans_p函数功能:生成解释结点函数原型:trans_p insert_trans_node_text(trans_p,trans_p)函数参数:trans_p,trans_p函数返回值类型:trans_p函数功能:解释结点插到解释链表尾部函数原型:word_p create_word_node_text(char *,trans_p)函数参数:char *,trans_p函数返回值类型:word_p函数功能:生成单词结点函数原型:word_p insert_word_node_text
17、(word_p,word_p)函数参数:word_p,word_p函数返回值类型:word_p函数功能:单词结点插到单词链表尾部函数原型:int get_trans_num(trans_p)函数参数:trans_p函数返回值类型:int函数功能:获取某个单词的解释个数函数原型:void print_hash(array_p)函数参数:array_p函数返回值类型:void函数功能:遍历哈希表函数原型:void print_word(word_p)函数参数:word_p函数返回值类型:void函数功能:遍历单词链表函数原型:void clear_space(char *)函数参数:char *函
18、数返回值类型:void函数功能:清除字符串后的空格5.5.2.2 模块2函数原型:void module2(void)函数参数:void函数返回值类型:void函数功能:建立二进制索引文件函数原型:void build_dat_index(array_p,char *)函数参数:array_p,char *函数返回值类型:void函数功能:生成二进制索引文件函数原型:index_p write_content_dat_index(array_p,char *)函数参数:array_p,char *函数返回值类型:index_p函数功能:将哈希表中的内容写进二进制文件,并保存每个单词所对的索引,
19、生成目录函数原型:long write_list_dat_index(index_p,char *,long *)函数参数:index_p,char *,long *函数返回值类型:long函数功能:将目录写进dat文件,并保存目录开始的索引和目录中单词的个数函数原型:void write_listkey_dat_index(long)函数参数:long函数返回值类型:void函数功能:将目录开始的索引写进dat文件函数原型:void write_wordnum_dat_index(long)函数参数:long函数返回值类型:void函数功能:将目录中单词的个数写进dat文件函数原型:inde
20、x_p insert_index_node_index(index_p,index_p)函数参数:index_p,index_p函数返回值类型:index_p函数功能:目录结点插到目录链表头部5.5.2.3 模块3函数原型:void module3(void)函数参数:void函数返回值类型:void函数功能:使用二进制索引文件进行单词查询函数原型:index_p load_memory_bin(char *,index_p)函数参数:char *,index_p函数返回值类型:index_p函数功能:将二进制索引文件中的目录加载到内存中,采用链表结构函数原型:long search_inde
21、x_bin(index_p,char *) 函数参数:index_p,char *函数返回值类型:long函数功能:目录链表中查找单词对应的索引函数原型:word_p search_word_with_index_bin(char *,long) 函数参数:char *,long函数返回值类型:word_p函数功能:dat中查找某个索引相对应的单词内容及解释5.5.2.4 模块4函数原型: void module4(void) 函数参数:void函数返回值类型:void函数功能:添加新词到自定义文本中函数原型:void write_word_mytext_insert(char *,char
22、*)函数参数:char *,char *函数返回值类型:void函数功能:写入新词及其解释到自定义文本6、 编码6.1 模块1代码#include <stdio.h>#include <stdlib.h>#include <string.h>#include <my_word.h>/*-*/* 模块1: 使用文本词库进行单词查询 */ /*-*/*1.使用文本词库进行单词查询*/ void module1(void)int i;char str30;array_p point=(array_p)malloc(sizeof(array_t);for
23、(i=0;i<26;i+)point->hashi=(first_p)malloc(sizeof(first_t);point->hashi->ch='a'+i;point->hashi->next=NULL;point=load_memory_text("dict.txt",point);while(1)printf("Please input word:");gets(str);clear_space(str);if(strcmp(str,"Exit")=0)return ;el
24、seword_p result=search_word_text(point,str);if(result=NULL)word_p result2=search_word_mytext("my_dict.txt",str);if(result2=NULL)printf("Sorry,word not found!n");elsetrans_p p=result2->head;while(p!=NULL)puts(p->trans_name);p=p->next;elsetrans_p p=result->head;while(p!
25、=NULL)puts(p->trans_name);p=p->next;/*2.文本词库加载到内存中,采用哈希表结构*/array_p load_memory_text(char *filename,array_p point)int i,j,m,c,flag;FILE *fp;word_p new_word;trans_p new_trans,trans_head;if(fp=fopen(filename,"r")=NULL)printf("Sorry,file open failed!n");return point;while(1)ch
26、ar bufferSIZE='0',strSIZE='0'flag=0;if(c=fgetc(fp)=EOF)fclose(fp);return point;if(c='#')trans_head=NULL;i=0,j=0;while(c=fgetc(fp)!='n')bufferi+=c;while(c=fgetc(fp)!='n')if(c!='')strj+=c;elsenew_trans=create_trans_node_text(str);trans_head=insert_trans_
27、node_text(trans_head,new_trans);j=0;for(m=0;m<SIZE;m+)strm='0'new_trans=create_trans_node_text(str);trans_head=insert_trans_node_text(trans_head,new_trans);new_word=create_word_node_text(buffer,trans_head);for(i=0;i<26;i+)if(buffer0=point->hashi->ch)flag=1;point->hashi->nex
28、t=insert_word_node_text(point->hashi->next,new_word);break;if(!flag)fclose(fp);return point;/*3.哈希表中查找单词*/word_p search_word_text(array_p point,char *str)int i;for(i=0;i<26;i+)if(str0=point->hashi->ch)word_p p=point->hashi->next;while(p!=NULL)if(strcmp(p->word_name,str)=0)ret
29、urn p;elsep=p->next;return NULL;return NULL;/*4.自定义文本词库中查找单词*/word_p search_word_mytext(char *filename,char *str)int i;array_p point=(array_p)malloc(sizeof(array_t);for(i=0;i<26;i+)point->hashi=(first_p)malloc(sizeof(first_t);point->hashi->ch='a'+i;point->hashi->next=NUL
30、L;point=load_memory_text(filename,point);word_p result=search_word_text(point,str);return result;/*5.生成解释结点*/trans_p create_trans_node_text(char *str)trans_p new=(trans_p)malloc(sizeof(trans_t);strcpy(new->trans_name,str);new->trans_length=strlen(str);new->next=NULL;return new;/*6.解释结点插到解释链
31、表尾部*/trans_p insert_trans_node_text(trans_p head,trans_p newnode)if(head=NULL)newnode->next=NULL;head=newnode;elsetrans_p p=head;while(p->next!=NULL)p=p->next;newnode->next=NULL;p->next=newnode;return head;/*7.生成单词结点*/word_p create_word_node_text(char *str1,trans_p head)word_p newnode
32、=(word_p)malloc(sizeof(word_t);strcpy(newnode->word_name,str1);newnode->word_length=strlen(newnode->word_name);newnode->head=head;newnode->next=NULL;newnode->trans_num=get_trans_num(newnode->head);return newnode;/*8.单词结点插到单词链表尾部*/word_p insert_word_node_text(word_p head,word_p n
33、ewnode)if(head=NULL)newnode->next=NULL;head=newnode;elseword_p p=head;while(p->next!=NULL)p=p->next;newnode->next=NULL;p->next=newnode;return head;/*9.获取某个单词的解释个数*/int get_trans_num(trans_p head)int length=0;trans_p p=head;while(p!=NULL)length+;p=p->next;return length;/*10.遍历哈希表*/v
34、oid print_hash(array_p point)int i;word_p p;for(i=0;i<26;i+)p=point->hashi->next;while(p!=NULL)puts(p->word_name);trans_p t=p->head;while(t!=NULL)printf("%s;",t->trans_name);t=t->next;putchar('n');p=p->next;return ;/*11.遍历单词链表*/void print_word(word_p head)wo
35、rd_p p=head;while(p!=NULL)puts(p->word_name);trans_p t=p->head;while(t!=NULL)printf("%s;",t->trans_name);t=t->next;putchar('n');p=p->next;return;/*12.清除字符串后的空格*/void clear_space(char *str)if(strstrlen(str)-1=' ')strstrlen(str)-1='0'clear_space(str);re
36、turn ;6.2 模块2代码#include <stdio.h>#include <stdlib.h>#include <string.h>#include <my_word.h>/*-*/* 模块2: 建立二进制索引文件 */*-*/*1.建立二进制索引文件*/void module2(void)int i;array_p point=(array_p)malloc(sizeof(array_t);for(i=0;i<26;i+)point->hashi=(first_p)malloc(sizeof(first_t);point-
37、>hashi->ch='a'+i;point->hashi->next=NULL;point=load_memory_text("dict.txt",point);build_dat_index(point,"dict.dat");return ;/*2.生成二进制索引文件*/void build_dat_index(array_p point,char *filename)FILE *fp;long word_num,start_index;fp=fopen(filename,"w");fcl
38、ose(fp);index_p head=write_content_dat_index(point,filename);start_index=write_list_dat_index(head,filename,&word_num);write_listkey_dat_index(start_index);write_wordnum_dat_index(word_num);printf("%ld words has been built finished!n",word_num);return ;/*3.将哈希表中的内容写进二进制文件,并保存每个单词所对的索引,
39、生成目录*/index_p write_content_dat_index(array_p point,char *filename)int i;FILE *fp;word_p p;trans_p t;index_p new,head;head=NULL;if(fp=fopen("dict.dat","ab")=NULL)printf("Sorry,file open failed!n");return NULL;elsefor(i=0;i<26;i+)p=point->hashi->next;while(p!=NU
40、LL)new=(index_p)malloc(sizeof(index_t);strcpy(new->word_name,p->word_name);new->position=ftell(fp);new->next=NULL;head=insert_index_node_index(head,new);fwrite(&p->word_length,sizeof(p->word_length),1,fp);fwrite(p->word_name,sizeof(p->word_name),1,fp);fwrite(&p->tr
41、ans_num,sizeof(p->trans_num),1,fp);t=p->head;while(t!=NULL)fwrite(&t->trans_length,sizeof(t->trans_length),1,fp);fwrite(t->trans_name,sizeof(t->trans_name),1,fp);t=t->next;p=p->next;fclose(fp);return head;/*4.将目录写进dat文件,并保存目录开始的索引和目录中单词的个数*/long write_list_dat_index(index
42、_p head,char *filename,long *word_num)FILE *fp;int t;index_p p=head;index_data new;*word_num=0;if(fp=fopen("dict.dat","ab")=NULL)printf("Sorry,file open failed!n");return 0;elset=ftell(fp);while(p!=NULL)strcpy(new.word_name,p->word_name);new.position=p->position;f
43、write(&new,sizeof(index_data),1,fp);(*word_num)+;p=p->next;fclose(fp);return t;/*5.将目录开始的索引写进dat文件*/void write_listkey_dat_index(long start_index)FILE *fp;if(fp=fopen("dict.dat","ab")=NULL)printf("Sorry,file open failed!n");return ;elsefwrite(&start_index,siz
44、eof(long),1,fp);fclose(fp);/*6.将目录中单词的个数写进dat文件*/void write_wordnum_dat_index(long word_num)FILE *fp;if(fp=fopen("dict.dat","ab")=NULL)printf("Sorry,file open failed!n");return ;elsefwrite(&word_num,sizeof(long),1,fp);fclose(fp);return;/*7.目录结点插到目录链表头部*/index_p inse
45、rt_index_node_index(index_p head,index_p newnode)newnode->next=head;head=newnode;return head;6.3 模块3代码#include <stdio.h>#include <stdlib.h>#include <string.h>#include <my_word.h>/*-*/* 模块3: 使用二进制索引文件进行单词查询 */*-*/*1.使用二进制索引文件进行单词查询*/void module3(void) char str30;long index;
46、index_p head=NULL;word_p result;trans_p t;head=load_memory_bin("dict.dat",head);while(1)printf("Please input word:");gets(str);clear_space(str);if(strcmp(str,"Exit")=0)return ;elseindex=search_index_bin(head,str);if(index=-1)printf("Sorry,word not found!n");el
47、seresult=search_word_with_index_bin("dict.dat",index);t=result->head;while(t!=NULL)puts(t->trans_name);t=t->next;/*2.将二进制索引文件中的目录加载到内存中,采用链表结构*/index_p load_memory_bin(char *filename,index_p head)FILE *fp;int i;long start_index,word_num;index_p new;index_data new_data;fp=fopen(fil
48、ename,"rb");if(fp=NULL)printf("Sorry,file open failed!n");return NULL;fseek(fp,-2*sizeof(long),SEEK_END); fread(&start_index,sizeof(long),1,fp);fread(&word_num,sizeof(long),1,fp);fseek(fp,start_index,SEEK_SET);for(i=0;i<word_num;i+)new=(index_p)malloc(sizeof(index_t);f
49、read(&new_data,sizeof(index_data),1,fp);strcpy(new->word_name,new_data.word_name);new->position=new_data.position;head=insert_index_node_index(head,new);fclose(fp);return head; /*3.目录链表中查找单词对应的索引*/long search_index_bin(index_p head,char *str) index_p p=head;while(p!=NULL)if(strcmp(p->word_name,str)=0)return p->position;p=p->next;return -1;/*4.dat中查找某个索引相对应的单词内容及解释*/word_p search_word_with_index_bin(char *filename,long position) FILE *fp;int i;word_p new;trans_p trans_node,trans_head=NULL;fp=fopen(filename,"rb&qu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 影响农村信用社发展的政策性障碍分析
- 轮椅车 第31部分 电动轮椅车的锂离子电池系统和充电器 要求和试验方法 征求意见稿
- 直播招商课件教学课件
- 金融培训课件教学课件
- 三年级数学计算题专项练习及答案集锦
- 维修水泵机组合同(2篇)
- 学习领会《新就业形态劳动者权益协商指引》心得体会
- 南京航空航天大学《编译原理》2022-2023学年第一学期期末试卷
- 发现问题说课稿
- 阳春市河朗镇饮用水供水工程施工组织设计
- 2019新教材人教版生物必修1教材课后习题答案
- 2024年中国白酒行业数字化转型研究报告-36氪-202409
- 《学校主人公:3 校园广播站》教学设计-2024-2025学年五年级上册综合实践活动沪科黔科版
- 外伤急救包扎技术说课课件
- 人教版(2024新版)七年级上册英语全册语法知识点讲义
- 全国青岛版信息技术七年级下册专题一第8课三、《高级统计-数据透视表》教学设计
- 2024年秋季新人教版七年级数学上册教学课件 第五章 一元一次方程 5.3实际问题与一元一次方程(第4课时)
- 清淡的晚餐(课件)六年级上册劳动北京版
- 妇科内分泌疾病诊断与治疗考核试卷
- 城镇雨污分流项目可行性研究报告
- 《19 海滨小城》公开课一等奖创新教学设计及反思
评论
0/150
提交评论