Advertisement

机器翻译(模拟)

阅读量:

题面(from luogu)
(背景: 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。)
该软件的工作原理较为基础,在处理过程中它会将每个输入的英文单词逐一转换为对应的中文含义。具体来说,在处理每一个英文单词时程序首先会在系统内搜索该单词对应的中文解释;如果当前系统内存在该词语及其译文,则直接调用其进行翻译;若未找到对应记录,则会调用外存词典获取对应解释,并将该词语及其译文存入系统以便后续操作。需要注意的是,在系统内存已满的情况下(即已存储 M 个词汇及其译文),新输入的词语会被自动替换掉最早被注入系统的词汇以腾出空间供新词汇使用。
假设一篇待译英语文章由 N 个英文字组成,请问在开始翻译之前系统内存为空的情况下该软件需要访问外存词典多少次才能完成全文翻译?

共两行数据输入。第一行为两个正整数值M,N,分别表示系统内存容量与待处理文本文件长度。
第二行为N个非负整数值,按照原文顺序排列,每个数字(范围在0到999之间)代表一个英文单词。
若两个单词在原文中相同,则对应的数字也相同。
系统输出结果为:完成整个文本处理过程中,系统总共调用了词典多少次。
输入样例:
3 7
1 2 1 5 4 4 1
输出样例:
5
详细过程如下:
每条记录依次表示当前处理过程中的内存状态变化情况:
空: 初始化状态为空状态。
第1步: 查找并引入单词1至内存中。
第2步: 查找并引入单词2至内存中。
第3步: 在内存中找到已存在的单词1,无需引入新词。
第4步: 查找并引入单词5至内存中。
第5步: 替换内存中的单词1为新引入的单词4.
第6步: 在内存中找到已存在的单词4.
第7步: 替换内存中的单词4为新引入的单词1.
整个处理流程共计查询词典5次.

题目分析
问题描述:给定一组数据序列共计n个元素,在处理过程中若新插入元素超出当前存储空间限制(最大容量m),则需将超出部分从前端依次删除以腾出存储空间给新元素。(题目的样例说明已经做了详细阐述)
观察发现:这与队列结构中先进先出的原则高度契合。基于此特性我们可以采用类似的方法来实现数据序列的动态管理与更新操作(便于后续开发和测试方案的设计与实现)。

为了管理队列,后来编写了一个毫无逻辑可言的算法

复制代码
    t=f[d];
    f[d]=p;
    for(int i = d - 1; i >= 1; i--)
    {
    if (i % 2 == 0) //这个就很那什么了。。。额。。。
            { 
                t1=f[i]; //两个变量螺旋交换(无视我在瞎扯)
                f[i]=t;             
            }           
                else
                    {
                        t=f[i];
                        f[i]=t1; 
                    }

通过这种方式进行维护的话,自然会导致失败(ACWAWAWAACWAAWAWA),因此设计了这样的编写方式:

复制代码
    for(int i = 1; i <= d-1; i++) 
    f[i]=f[i+1];    //从前向后推
    f[d]=p; //霸占挤出的位置

同上面那个额。。。(我也不想多说)好多了。。吧(勉强之笑)

代码

复制代码
    #include <bits/stdc++.h> 
    using namespace std;
    
    int k[10009],f[10009],m,n,i,d=1,ans=1; //d的初值要是1,因为是从第一个开始找的,同样,ans也要是1,因为第一个数已经调用了
    
    int find(int c) //判读是否需要维护
    {
    for(int i = 1; i <= d; i++)
        if (c == f[i]) return 1; //找到了,直接return
    return 0; //反之,需要进行维护
    }
    
    void get_more(int p)
    {
    int t=0,t1=0;
    ans++; //进行统计
    if (d < m)  //如果队列没有超出其范围
        {
            d++; //向后拓展一个元素位置
            f[d]=p; //置入
        }
            else 
                {
                //  t=f[d]; //恶心的大宝贝
                //  f[d]=p;
                //  for(int i = d - 1; i >= 1; i--)
                //      {
                //          if (i % 2 == 0)
                //              {
                //                  t1=f[i];
                //                  f[i]=t;             
                //              }           
                //                  else
                //                      {
                //                          t=f[i];
                //                          f[i]=t1; 
                //                      }   
    
                    for(int i = 1; i <= d-1; i++)
                        f[i]=f[i+1];    //从前向后推
                    f[d]=p;  //霸占挤出的位置
                }
    }
    
    int main()
    {
    cin>>m>>n;   //输入
    for (int i = 1; i <= n; i++)
        cin>>k[i];
    
    f[1]=k[1]; //先取第一个
    for (int i = 2; i <= n; i++) //开始处理队列
    {   
        if (find(k[i]) == 0) get_more(k[i]); //判断是否需找
    //  if (d < m) d++; //之前的赘笔,之后再“get_more”函数中已经覆盖此功能了
    //  for (int i = 1; i <= d; i++)
        //cout<<f[i]<<' ';
    //  cout<<endl;
    }
    
    //  for (int i = 1; i <= m; i++)
    //  cout<<f[i];
    cout<<ans; //输出
    }
复制代码
                                               **蒟蒻新星c_uizrp_dzjopkl原创**

全部评论 (0)

还没有任何评论哟~