换行算法

本文介绍了一种基于贪婪算法和另一种基于动态规划的Knuth算法来实现文本换行的方法。这两种算法能够有效地处理文本布局问题,确保文本在限定宽度内美观地换行。贪婪算法简单直接,而Knuth算法考虑了更多因素,追求更佳的视觉效果。
摘要由CSDN通过智能技术生成
/* 换行*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<sstream>
#include<vector>
#define INT_MAX 2147483647
using namespace std;
const int Line_size=45;

void GetWords(const string& text, vector<string>& words_array)//获取单个 词语
{
    string::const_iterator word_begin, word_end;
    word_begin = word_end = text.begin();

    while (word_begin != text.end())
    {
        if (!isgraph(*word_begin))
        {
            ++word_begin;
            ++word_end;
            continue;
        }

        if (isgraph(*word_end))
        {
            ++word_end;
        }
        else
        {
            words_array.push_back(string(word_begin, word_end));
            word_begin = word_end;
        }
    }
}

string WordWarpGreedy(const string& text, int line_size)
{
    int line_space;
    vector<string>::iterator it;

    vector<string> words_array;
    stringstream outstr;

    GetWords(text, words_array);

    for (it = words_array.begin(), line_space = line_size;it != words_array.end(); ++it)
    {
        if ((line_space -= it->length()) >= 0)
        {
            outstr << (*it);
        }
        else
        {
            outstr << '\n' << (*it);
            line_space = line_size - it->length();
        }

        if (line_space)
        {
            outstr << ' ';
            --line_space;
        }
    }

    return outstr.str();
}

inline int CostFunc(const vector<string> words_array, int line_size,unsigned int begin, unsigned int end)
{
    unsigned int i;
    int t, cost;

    for (i = begin, t = 0; i <= end; ++i)
    {
        t += words_array[i].length();
    }

    cost = line_size - (end - begin) - t;

    if (cost < 0)
    {
        return -1;
    }

    return cost * cost;
}
string WordWarpKnuth(const string& text, int line_size)
{
    unsigned int i, j, p;
    int t, min;

    vector<string> words_array;
    stringstream outstr;

    GetWords(text, words_array);

    int cost[words_array.size()];
    int lines[words_array.size()];

    i = 0;
    while(i < words_array.size() && (t = CostFunc(words_array, line_size, 0, i)) >= 0)
    {
        cost[i] = t;
        lines[i++] = 0;
    }

    for(;i < words_array.size(); ++i)
    {
        for(j = i - 1, min = INT_MAX; j > 0; --j)
        {
            t = CostFunc(words_array, line_size, j + 1, i);

            if(t >= 0)
            {
                if(t + cost[j] < min)
                {
                    min = t + cost[j];
                    p = j;
                }
            }
            else
            {
                break;
            }
        }

        cost[i] = min;

        lines[i] = p + 1;
    }

    i = words_array.size() - 1;

    while(i > 0)
    {
        j = lines[i];

        while(i > j)
        {
            lines[i--] = j;
        }

        if(i == 0)
        {
            lines[i] = j;
        }
        else
        {
            lines[i--] = j;
        }
    }

    outstr << words_array[0] << ' ';

    for(i = 1; i < words_array.size(); ++i)
    {
        if(lines[i] != lines[i - 1])
        {
            outstr << '\n';
        }

        outstr << words_array[i] << ' ';
    }

    return outstr.str();
}




int main()
{
    //freopen("cyk.txt","r",stdin);
     //freopen("cyk12.txt","w",stdout);
    string a;
     vector<string> m1;
    getline(cin,a);
    cout<<WordWarpGreedy(a,Line_size);
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值