KWIC算法(置换索引)的一个简单应用

题目如下:
设计并实现一个程序来产生置换索引。置换索引指的是,每个短语都是以这个短语中的每个单词为索引的。所以,当给定下面的输入时:
The quick brown fox
jumped over the fence
输出应该是:
The quick brown fox
jumped over the fence
The quick brown fox
jumped over the fence
jumped over the fence
The quick brown fox
jumped over the fence
The quick brown fox
有一个推荐的算法。它分三步来解决这个问题:
1、读取每行输入,并生成一个改行的轮转集合。每次轮转都把输入中的下一个单词放在第一个位置上,并把原先的第一个单词轮转到短语的末尾。所以第一行输入的短语产生的输出是:
The quick brown fox
quick brown fox The
brown fox The quick
fox The quick brown
当然,很重要的是要知道原先的短语在哪里结束,轮转后的短语又从哪里开始。
2、对所有轮转排序。
3、反向轮转并输出置换索引,其中还包含分隔符,把短语重新连接在一起,并且以适当的格式输出。
部分程序如下(不完善有待改进,以后再说)
// PE5-1.设计并实现一个程序来产生置换索引(permuted index)
// 时间:2012-12-27 19:57:07
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <cctype>    // 函数tolower
#include <algorithm> // 函数max

using namespace std;

// 排序比较函数
bool compare(const string& s, const string& t)
{
    // 将string中的大写转换为小写
    string temp1, temp2;
    string::size_type i = 0,j = 0;
    while (i != s.size())
    {
        temp1 += tolower(s[i]);
        i++;
    }

    while (j != t.size())
    {
        temp2 += tolower(t[j]);
        j++;
    }

    return temp1 < temp2;
}

// 找出list中最长的字符串的长度
string::size_type width(const list<string>& v)
{
    list<string> t = v;
    string::size_type maxlen = 0;
    for (list<string>::iterator iter= t.begin(); iter != t.end(); ++iter)
    {
        maxlen = max(maxlen, (*iter).size() );
    }
    return maxlen;
}

// 分割字符串
list<string> split(const string& s)
{
    list<string> ret;
    typedef string::size_type string_size;
    string_size i = 0;

    //
    while (i != s.size())
    {
        while (i != s.size() && isspace(s[i]))
        {
            ++i;
        }

        //
        string_size j = i;
        //
        while (j != s.size() && !isspace(s[j]))
        {
            ++j;
        }

        if (i != j)
        {
            ret.push_back(s.substr(i, j-i));
            i = j;
        }
    }
    return ret;
}

int main()
{
    cout << "请输入一段文字:" << endl;

    string words;
    list<string> texts, ntexts;

    // 不变式:到目前为止,texts包含了所有的单词数
    while (cin >> words && (words != "EOF"))
    {
        texts.push_back(words);
    }

    // 轮转前短句先赋给ntexts
    string str;
    for (list<string>::iterator iter = texts.begin();
             iter != texts.end(); iter++)
    {
        str = str + (*iter) + " ";
    }
    ntexts.push_back(str);

    // 获得首元素和最后一个元素
    string first = texts.front();
    string end   = texts.back();

    // 获得迭代器
    list<string>::iterator first_iter = texts.begin();
    list<string>::iterator end_iter   = texts.end();
    while (*first_iter != end)
    {
        // 把首元素转到末尾
        list<string>::iterator temp = texts.begin();
        texts.push_back(*temp);   // 以下两句代码位置不能互掉
		texts.erase(temp);

        string str;
        for (list<string>::iterator iter = texts.begin();
             iter != texts.end(); iter++)
        {

            str = str + (*iter) + " ";
        }
        ntexts.push_back(str);

        first_iter = texts.begin();
        end_iter   = texts.end();
    }

    cout << "轮转集合是:" << endl;
    list<string>::iterator niter = ntexts.begin();
    // 找出ntexts中最长字符串
    string::size_type width1 = width(ntexts);
    for (; niter != ntexts.end(); niter++)
    {
        cout << *niter << endl;
    }

    // 给ntexts排序
    ntexts.sort(compare);

    cout << "排序后的轮转集合是:" << endl;
    for (niter = ntexts.begin(); niter != ntexts.end(); niter++)
    {
        cout << *niter << endl;
    }

    list<string> nt1, nt2;
    list<string>::iterator iter = ntexts.begin();
    while (iter != ntexts.end())
    {
        list<string> lwords = split(*iter);
        list<string>::iterator l_itrer = lwords.begin();
        string s;
        if (*l_itrer == first)
        {   // 首元素为first
            for (; l_itrer != lwords.end(); ++l_itrer)
            {
                s += *l_itrer + " ";
            }
            nt1.push_back(s + string(width1-s.size(), ' '));
            nt2.push_back(string(width1, ' '));
            s = " ";  // 清空s
        }
        else if (*l_itrer == end)
        {   // 首元素为end
            s = *l_itrer + " ";
            nt1.push_back(s + string(width1-s.size(), ' '));

            s = " "; // 清空s
            for (++l_itrer; l_itrer != lwords.end(); ++l_itrer)
            {
                s += *l_itrer + " ";
            }
            nt2.push_back(string(width1-s.size(), ' ') + s);
        }
        else
        {   // 其他情况下
            do
            {
                s += *l_itrer + " ";
                ++l_itrer;
            }while (*l_itrer != first);
            nt1.push_back(s + string(width1-s.size(), ' '));
            s = " ";
            for (; l_itrer != lwords.end(); ++l_itrer)
            {
                s += *l_itrer + " ";
            }
            nt2.push_back(string(width1-s.size(), ' ') + s);
        }

        ++iter;
    }

    list<string>::iterator nit1 = nt1.begin();
    list<string>::iterator nit2 = nt2.begin();
    cout << "最终的结果是:" << endl;
    for (; nit1 != nt1.end(); ++nit1, ++nit2)
    {
        cout << *nit2 << " " << *nit1 << endl;
    }

    return 0;
}
<未完待续>



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值