基于线性表或二叉排序树的低频词过滤系统

问题描述:对于一篇给定的英文文章,分别利用线性表或二叉排序树来实现单词频率的统计,实现低频词的过滤,并比较两种方法的效率。

来这看的估计都是想搞数据结构课程设计吧,不知道有没有跟我同一个老师的,拿走后记得修改一下下

注意单步执行需要按顺序,不想这样的话可以自己修改函数

功能要求:

1. 读取英文文章文件(InFile.txt),识别其中的单词。

2. 分别利用线性表和二叉排序树构建单词的存储结构。当识别出一个单词后,若线性表或者二叉排序树中没有该单词,则在适当的位置上添加该单词;若该单词已经被识别,则增加其出现的频率。

3. 统计结束后,删除出现频率低于五次的单词,并显示该单词和其出现频率。

4.其余单词及其出现频率按照从高到低的次序输出到文件中(OutFile.txt),同时输出用两种方法完成该工作所用的时间。

5.计算查找表的ASL值,分析比较两种方法的效率。

6.系统运行后主菜单如下:

当选择1后进入以下界面:

其中选择2时显示利用线性表来实现所有功能所用的时间。

当在主菜单选择2二叉排序树后,进入的界面与上图类同。

实现提示:

1、在统计的过程中,分词时可以利用空格或者标点符号作为划分单词依据,文章中默认只包含英文单词和标点符号。

2、对单词进行排序时,是按照字母序进行的,每个结点还应包含该单词出现的频率。

3、存储结构的定义

直接贴完整代码

代码太长了没办法一次性粘贴,分成了四部分

如果有什么问题,欢迎指正

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <time.h>
#include <math.h>
#include <string.h>
#include <windows.h>
#include <iomanip>
using namespace std;
ofstream oF;
ifstream iF;
string fn;
typedef struct Node // 结点结构
{
    string data;
    int count;
    struct Node *next;
    struct Node *lchild, *rchild;
} * BSTNode, *BSTree, *Link, *Linklist;
typedef struct Lnode
{
    BSTree tree[200];
    int top;
} Lnode, link; //结构体,节点=0;
link s;
void InitStack() //栈初始化
{
    s.top = 0;
}
int StackEmpty() //判断栈是否为空栈
{
    if (s.top == 0)
        return 1;
    else
        return 0;
}
void Push(BSTree t) //入栈
{
    s.top++;
    s.tree[s.top] = t;
}
void Pop() //出栈
{
    s.top--;
}
int com(string a, string b) //验证a与b的大小(按照字母顺序)
{
    int i, j;
    for (i = 0; i < a.length(), i < b.length(); i++)
    {
        if (a[i] > b[i])
            return 0;
        if (a[i] < b[i])
            return 1;
    }
    if (i == a.length() - 2)
        return 1;
    else
        return 0;
}
void Linkinsert(Linklist &L, string a)//在当前位置的后一位插入
{
    Link o = new Node;
    o->data = a;
    o->count = 1;
    o->next = L->next;
    L->next = o;
}
void link_read(Linklist &L)//从文件中读取文章,并将单词按字母顺序排列
{
    L = new Node;
    L->next = NULL;
    Link p, q;
    string l, w;
    char t;
    iF.open(fn);
    while (iF.get(t))
    {
        if (t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' || t == '\'')//一个字符一个字符读入
        {
            if (t >= 'A' && t <= 'Z')
                t += 32;
            w += t;
        }
        else
        {
            if (w == "")
                continue;
            q = L;
            p = q->next;
            while (p)
            {
                if (p->data == w)
                {
                    w = "";
                    p->count++;
                    break;
                }
                q = p;
                p = p->next;
            }
            if (w != "")
            {
                q = L;
                p = q->next;
                while (p)
                {
                    if (com(w, p->data))
                        break;
                    q = p;
                    p = q->next;
                }
                Linkinsert(q, w);
                w = "";
            }
        }
    }
    iF.close();
}
void linkshow(Linklist l)//输出链表
{
    Link p;
    int a = 0;
    p = l->next;
    while (p)
    {
        a++;
        cout.setf(ios::left);
        cout << setw(15) << p->data << " " << setw(2) << p->count << " ";
        cout.unsetf(ios::left);
        if (a % 3 == 0)
            cout << endl;
        p = p->next;
    }
    cout << endl;
    return;
}
void link_delete(Linklist &l)//删除低频词汇
{
    cout << "低频词汇如下所示:\n";
    int a = 0;
    Link p, q;
    q = l;
    p = q->next;
    while (p)
    {
        if (p->count < 5)
        {
            a++;
            cout.setf(ios::left);
            cout << setw(15) << p->data << " " << setw(2) << p->count << " ";
            cout.unsetf(ios::left);
            Link o = p;
            q->next = o->next;
            free(o);
            p = q->next;
            if (a % 3 == 0)
                cout << endl;
            continue;
        }
        q = p;
        p = q->next;
    }
    cout << endl;
}
void Linksort(Linklist &l)//按频率给数据排序
{
    Link p, q, r;
    r = l;
    while (r->next->next)
    {
        q = r->next;
        p = q->next;
        while (p)
        {
            if (p->count > r->next->count)
            {
                q->next = p->next;
                p->next = r->next;
                r->next = p;
                p = q->next;
                continue;
            }
            q = p;
            p = p->next;
        }
        r = r->next;
    }
}
void linkwrite(Linklist L)//写入文件
{
    oF.open("Link_OutFile.txt");
    oF.setf(ios::left);
    oF << "高频单词及其频率如下:" << endl;
    Link p;
    p = L->next;
    while (p)
    {
        oF.setf(ios::left);
        oF << setw(15) << p->data << " " << setw(2) << p->count << endl;
        oF.unsetf(ios::left);
        p = p->next;
    }
    oF.close();
    return;
}
void linkASL(Linklist L)//求出链表的ASL值
{
    int a = 0, b = 0;
    Link p;
    p = L->next;
    while (p)
    {
        a++;
        b += a;
        p = p->next;
    }
    cout << "链表的ASL值为:" << b * 1.0 / a << endl;
    return;
}
void BSTInsert(BSTree &T, string e)//二叉排序树按字母顺序插入数据
{
    if (!T)
    {
        BSTNode o = new Node;
        o->data = e;
        o->count = 1;
        T = o;
        T->lchild = NULL;
        T->rchild = NULL;
    }
    else if (T->data == e)
    {
        T->count++;
        return;
    }
    else if (!com(T->data, e))
        BSTInsert(T->lchild, e);
    else
        BSTInsert(T->rchild, e);
}
void BSTread(BSTree &T)//从文件中读取文章到二叉树
{
    T = new Node;
    T = NULL;
    Link a = new Node;
    string w;
    char t;
    iF.open(fn);
    while (iF.get(t))
    {
        if (t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' || t == '\'')
        {
            if (t >= 'A' && t <= 'Z')
                t += 32;
            w += t;
        }
        else
        {
            if (w == "")
                continue;
            BSTInsert(T, w);
            w = "";
        }
    }

    iF.close();
}
void BSTwrite(BSTree T)//将二叉树按照中序写入文件
{
    int a = 0;
    InitStack();
    BSTree t = T;
    oF.open("BST_OutFile.txt");
    oF.setf(ios::left);
    oF << "高频单词及其频率如下:" << endl;
    oF.setf(ios::left);
    while (t || !StackEmpty())
    {
        while (t)
        {
            Push(t);
            t = t->lchild;
        }
        if (!StackEmpty())
        {
            t = s.tree[s.top];
            Pop();
            oF << setw(15) << t->data << " " << setw(2) << t->count << endl;
            t = t->rchild;
        }
    }
    oF.close();
    oF.unsetf(ios::left);
}
void BSTshow(BSTree T) //中序输出
{
    int a = 0;
    InitStack();
    BSTree t = T;
    while (t || !StackEmpty())
    {
        while (t)
        {
            Push(t);
            t = t->lchild;
        }
        if (!StackEmpty())
        {
            t = s.tree[s.top];
            Pop();
            cout.setf(ios::left);
            cout << setw(15) << t->data << " " << setw(2) << t->count << " ";
            cout.unsetf(ios::left);
            a++;
            if (a % 3 == 0)
                cout << endl;
            t = t->rchild;
        }
    }
    cout << endl;
}
void BSTorder(BSTree &T, BSTNode e)//按出现频率顺序插入二叉树中
{
    if (!T)
    {
        BSTNode o = new Node;
        o->data = e->data;
        o->count = e->count;
        T = o;
        T->lchild = NULL;
        T->rchild = NULL;
        return;
    }
    if (T->count < e->count)
    {
        BSTorder(T->lchild, e);
    }
    if (T->count > e->count)
    {
        BSTorder(T->rchild, e);
    }
    if (T->count == e->count)
    {
        if (com(T->data, e->data))
        {
            BSTorder(T->rchild, e);
        }
        else
        {
            BSTorder(T->lchild, e);
        }
    }
}
void BSTDelete(BSTree &T)//删除低频词汇
{
    BSTree o = new Node;
    o = NULL;
    int a = 0;
    InitStack();
    BSTree t = T;
    while (t || !StackEmpty())
    {
        while (t)
        {
            Push(t);
            t = t->lchild;
        }
        if (!StackEmpty())
        {
            t = s.tree[s.top];
            Pop();
            if (t->count < 5)
            {
                cout.setf(ios::left);
                cout << setw(15) << t->data << " " << setw(2) << t->count << " ";
                cout.unsetf(ios::left);
                a++;
                if (a % 3 == 0)
                    cout << endl;
                t = t->rchild;
            }
            else
            {
                BSTorder(o, t);
                t = t->rchild;
            }
        }
    }
    T = o;
    cout << endl;
}
int BSTnodecnt(BSTree T)//计算二叉树总结点数
{
    int d = 0;
    if (!T)
        return 0;
    else
    {
        d = 1 + BSTnodecnt(T->lchild) + BSTnodecnt(T->rchild);
    }
    return d;
}
int BSTasl(BSTree t, int d)//计算二叉树总权值
{
    d++;
    int a = d;
    if (t->lchild)
        d += BSTasl(t->lchild, a);
    if (t->rchild)
        d += BSTasl(t->rchild, a);
    return d;
}
void BSTaslplus(BSTree T)//返回二叉树ASL值
{
    cout << "该二叉排序树ASL值为:" << BSTasl(T, 0) * 1.0 / BSTnodecnt(T) << endl;
    return;
}
void ui1()
{
    cout << "1、线性表" << endl;
    cout << "2、二叉排序树" << endl;
    cout << "3、退出系统" << endl;
    cout << "请输入你需要的服务,输入数字(1-3):";
    return;
}
void ui2()
{
    cout << "1、连续执行完毕" << endl;
    cout << "2、显示执行时间" << endl;
    cout << "3、单步执行:识别并统计单词" << endl;
    cout << "4、单步执行:删除并显示出低频率单词" << endl;
    cout << "5、单步执行:输出其余单词及其频率" << endl;
    cout << "6、单步执行:计算并输出ASL值" << endl;
    cout << "7、返回主菜单" << endl;
    return;
}
int main()
{
    cout << "请输入文件名(不包含后缀,注意大小写):";
    while (1)
    {
        cin >> fn;
        fn += ".txt";
        iF.open(fn);
        if (!iF.is_open())
        {
            cout << "请检查文件名是否输入正确,或文件是否与程序放在同一目录!\n\n请重新输入:";
        }
        else
        {
            iF.close();
            break;
        }
    }
    Linklist Li;
    BSTree Tr;
    int flag1, flag2, t;
    while (1)
    {
        system("cls");
        ui1();
        cin >> flag1;
        switch (flag1)
        {
        case 1:
            system("cls");
            while (1)
            {
                ui2();
                cin >> flag2;
                if (flag2 == 1)
                {
                    system("cls");
                    link_read(Li);
                    cout << "所有单词及其频率如下:\n";
                    linkshow(Li);
                    link_delete(Li);
                    Linksort(Li);
                    cout << "高频词汇如下所示:\n";
                    linkshow(Li);
                    cout<<"已输出至本程序目录下\n";
                    linkwrite(Li);
                    linkASL(Li);
                }
                if (flag2 == 2)
                {
                    DWORD start, end;
                    start = GetTickCount();
                    link_read(Li);
                    link_delete(Li);
                    Linksort(Li);
                    linkwrite(Li);
                    linkASL(Li);
                    end = GetTickCount();
                    t = end - start;
                    system("cls");
                    cout << "共耗时" << t << "ms\n";
                }
                if (flag2 == 3)
                {
                    system("cls");
                    cout << "所有单词及其频率如下:\n";
                    link_read(Li);
                    linkshow(Li);
                }
                if (flag2 == 4)
                {
                    system("cls");
                    link_delete(Li);
                }
                if (flag2 == 5)
                {
                    system("cls");
                    cout << "高频单词及其频率如下:\n";
                    Linksort(Li);
                    linkshow(Li);
                    cout<<"已输出至本程序目录下\n";
                }
                if (flag2 == 6)
                {
                    system("cls");
                    linkASL(Li);
                }
                if (flag2 == 7)
                    break;
            }
            break;
        case 2:
            system("cls");
            while (1)
            {
                ui2();
                cin >> flag2;
                if (flag2 == 1)
                {
                    system("cls");
                    BSTread(Tr);
                    cout << "所有词汇及其频率如下:\n";
                    BSTshow(Tr);
                    cout << "低频词汇及其频率如下:\n";
                    BSTDelete(Tr);
                    cout << "高频词汇及其频率如下:\n";
                    BSTshow(Tr);
                    cout<<"已输出至本程序目录下\n";
                    BSTwrite(Tr);
                    BSTaslplus(Tr);
                }
                if (flag2 == 2)
                {
                    DWORD start, end;
                    start = GetTickCount();
                    BSTread(Tr);
                    BSTshow(Tr);
                    BSTDelete(Tr);
                    BSTwrite(Tr);
                    BSTaslplus(Tr);
                    system("cls");
                    end = GetTickCount();
                    t = end - start;
                    cout << "共耗时" << t << "ms\n";
                }
                if (flag2 == 3)
                {
                    system("cls");
                    cout << "所有词汇及其频率如下:\n";
                    BSTread(Tr);
                    BSTshow(Tr);
                }
                if (flag2 == 4)
                {
                    system("cls");
                    cout << "低频词汇及其频率如下:\n";
                    BSTDelete(Tr);
                }
                if (flag2 == 5)
                {
                    system("cls");
                    cout << "高频词汇及其频率如下:\n";
                    BSTshow(Tr);
                    cout<<"已输出至本程序目录下\n";
                    BSTwrite(Tr);
                }
                if (flag2 == 6)
                {
                    system("cls");
                    BSTaslplus(Tr);
                }
                if (flag2 == 7)
                    break;
            }
            break;
        case 3:
            return 0;
        }
    }
}

  • 12
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chang乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值