第四次作业
2016-03-22 20:37 梁开宝 阅读(218) 评论(4) 编辑 收藏 举报结对对象:郭自轻 微博地址:http://www.cnblogs.com/mengshen/ 贡献比例:50% /50%
基于作业3的结果,读取一个较小的文本文件A_Tale_of_Two_Cities.txt,统计该文件中的单词的频率,并将统计结果输出到当前目录下的 Result1.txt 文件。 (第一阶段初稿完成该要求)
- 命令行格式: 提示符> Myapp.exe -f filename.txt > Result.txt (PS:C++ 程序,Java 程序输出方式类似) filename.txt 为前面下载的文件名。
- 解释:
- 选项 -f 表示后面跟文件名
- 输出格式规定(参考作业3中的示例):
- 首先按照频率由高到低排序
- 频率一样的词, 按照字典顺序排序
- 此外, 读取一个较大的文本文件Gone_with_the_wind.txt实验对比程序执行效率,做如下改进,比较改进前后程序执行时间。
- 我的部分源程序:
-
typedef
struct
{
char
word[MAX_CHARACTER];
// 存储单词,不超过50个字符
int
count;
// 单词出现次数
} ElemType;
typedef
struct
{
ElemType *elem;
// 存储空间基址
int
length;
// 当前长度
int
listsize;
// 当前分配的存储容量(以sizeof(ElemType)为单位)
} SqList;
// 线性表的初始化
int
SqListInit ( SqList *L )
{
// 构造一个空的线性表L
L->elem = ( ElemType * )
malloc
( LIST_INIT_SIZE *
sizeof
( ElemType ) );
if
( !L->elem )
return
OVERFLOW;
// 存储分配失败
L->length = 0;
L->listsize = LIST_INIT_SIZE;
return
OK;
}
// 线性表的插入
int
SqListInsert ( SqList *L,
int
i,
char
*fword )
{
// 在顺序线性表L中第i个位置之前插入新的元素e
// i的合法值为1≤i≤L.Length + 1
if
( i < 0 || i > L->length )
{
printf
(
"i的值不合法!"
);
return
ERROR;
// i的值不合法
}
if
( L->length >= L->listsize )
{
// 当前存储空间已满,增加分配
ElemType *newbase = ( ElemType * )
realloc
( L->elem,
( L->listsize + LISTINCREMENT ) *
sizeof
( ElemType ) );
if
( !newbase )
return
OVERFLOW;
// 存储分配失败
L->elem = newbase;
// 新基址
L->listsize += LISTINCREMENT;
// 增加存储容量
}
ElemType *p, *q;
q = &L->elem[i];
for
( p = &L->elem[L->length - 1]; p >= q; p-- )
// 插入位置之后元素逐个右移
{
* ( p + 1 ) = *p;
}
strcpy
( q->word, fword );
// 复制fword中的字符到L->elem[i-1].word中
L->elem[i].count = 1;
// 设置计数初值为1
L->length++;
// 表长增1
return
OK;
}
// 线性表二分法查找
int
SqListBSearch ( SqList *L,
char
*sword,
int
&i )
{
if
( L->length == 0 )
// 当线性表为空时
{
i = 0;
// i返回单词插入位置
return
ERROR;
}
// 线性表不空时,在线性表L中查找元素sword,用i返回其在线性表中的位置
int
low = 0, high = L->length - 1, mid = L->length;
while
( low <= high )
{
mid = ( low + high ) / 2;
int
k =
strcmp
( L->elem[mid].word, sword );
if
( k == 0 )
// 待查单词sword等于中间值,找到待查元素
{
i = mid;
return
OK;
// 查找成功,函数返回值为1,用i返回所查元素在线性表中的位置
}
else
if
( k > 0 )
// 待查单词sword小于中间值,继续在前半区间进行查找
{
high = mid - 1;
i = low;
}
else
// 待查单词sword大于中间值,继续在后半区间进行查找
{
low = mid + 1;
i = high + 1;
}
}
return
ERROR;
// 线性表中不存在待查元素,函数返回值为0,i返回单词插入位置
}
void
SqListPrint (
FILE
*f,
char
fname[], SqList *L )
{
fprintf
( f,
"文档 %s 中总计有%d个单词\n"
, fname, L->length );
// 输出统计信息,L->length为单词个数
fprintf
( f,
"序号 单词 个数\n"
);
for
(
int
i = 0, j = 1 ; i < L->length ; i++, j++ )
// j-序号
fprintf
( f,
"%-5d %-20s %d\n"
, j, L->elem[i].word, L->elem[i].count );
}
- 运行结果:
- 两个人一直琢磨着,好难啊,刚好两个人C++基础差,完成得很艰难,不过同学对我的帮助特别的大,很感谢他。github:https://github.com/liangkaibao/disicizuoye