使用stl以不同方式拆分字符串

时间:2013-06-29 03:17:37

标签: c++ string stl split

我有一个字符串“子弹武器对装甲的伤害更小。”并且有条件这个字符串必须以不同的方式基于参数int width = 20分成几部分。

1.给出特定宽度的文字。

“子弹武器对装甲的伤害较小。”变

"Bullet weapons do le"
"ss damage against ar"
"mor."
  1. 包装给定特定宽度的文本,但除非绝对必要,否则不会分割单词。

    “子弹武器对装甲的伤害较小。”变成

    “子弹武器做” “减少伤害” “盔甲。”

  2. 3.给出具有特定宽度的文本,除非绝对必要,否则不会分割单词。换行时,此功能将尝试在宽度方面尽可能地制作线条。

    "Bullet weapons do less damage against armor." becomes
    
    "Bullet weapons "
    "do less damage "
    "against armor."
    

    对于案例1:我写了如下逻辑:

         int len=text.length();   where text is string text= "Bullet weapons do less damage     against armor."
    
    int last=0,first=0;
    
        vector<string> output;
    
    
    
    int max=ceil((double)len/width);
    cout<<max<<endl;
    
    
    
    for(int i=0;i<max;i++)
    {
    
        first=width*i;
        if(len<(width+(width*i)))
        {
            last=len;
        }
        else
        {
            last=width+(width*i);
        }
    
    
        string s(text,first,last);
        output.push_back(s);
    
    
    }
    

    但它给我结果如下:

    子弹武器   对装甲的伤害。   铁道部。  在第二行中它应该达到“ss对ar的损害”,其中逻辑错误;

    案例(2)和(3)如何。

    请帮帮我

    由于

3 个答案:

答案 0 :(得分:0)

构造函数的第三个参数是要构造的字符串的 length ,而不是最后一个字符的偏移量。

答案 1 :(得分:0)

  1. 您应该更改

    string s(text,first,last); --> string s(text,first,width);
    
  2. 您应该考虑将字符串拆分为单词,然后将这些单词添加到另一个字符串并检查其长度。

    int i = -1;
    string word = "";
    string part = "";
    do
    {
        i = text.find(' ');
        if (i != -1)
        {
            word = text.substr(0, i);
            text = text.substr(i + 1);
            if (word.length() + part.length() < width)
            {
                part += " " + word;
            }
            else
            {
                output.push_back(part);
                cout << part << endl;
                part = word;
            }
        }
        else
        {
            word = text;
            if (word.length() + part.length() < width)
            {
                part += " " + word;
                output.push_back(part);
                cout << part << endl;
            }
            else
            {
                output.push_back(part);
                cout << part << endl;
                output.push_back(word);
                cout << word << endl;
            }
        }
    } while (i != -1);
    
  3. 在执行类似于案例2

  4. 之前,您应该重新计算宽度

答案 2 :(得分:0)

案例1: 正如其他人已经指出的那样,您的示例中的字符串构造函数稍有错误,该行应为:

string s(text,first,width);

案例2: 我建议从一个等于最大允许宽度的子串开始,然后向后搜索空格,如下所示:

while (!text.empty())
{
    // Search backwards for a space. If we don't find one, break at the
    // maximum width.
    size_t line_width = text.rfind(' ', width - 1);
    if (line_width == string::npos)
    {
        line_width = width;
    }

    string current_line(text, 0, line_width);
    text = text.substr(line_width + 1);

    cout << current_line << endl;
}

案例3: 为此,您似乎需要以某种方式找出宽度为您提供最常规长度的线条。可能有几种方法可以做到这一点,但我想到的解决方案是多次运行算法,每次减小宽度,每次跟踪每条线的宽度比该宽度短(称为“宽度”区别”)。然后解决方案是总宽度差最小的一组线。

vector<string> best_line_set;
size_t best_total_width_difference = std::numeric_limits<size_t>::max();

for (j = width; j > 4; --j)
{
    string original_text(text);

    vector<string> current_line_set;
    size_t current_total_width_difference = 0;

    while (!text.empty())
    {
        // Search backwards for a space. If we don't find one, break at the
        // maximum width.
        size_t line_width = text.rfind(' ', j - 1);
        if (line_width == string::npos)
        {
            line_width = j;

            string current_line(text, 0, line_width);
            text = (line_width < text.size())
                ? text.substr(line_width)
                : "";

            current_line_set.push_back(current_line);
        }
        else
        {
            current_total_width_difference += j - line_width;

            string current_line(text, 0, line_width);
            text = (line_width + 1  < text.size())
                ? text.substr(line_width + 1)
                : "";

            current_line_set.push_back(current_line);
        }
    }

    if (current_total_width_difference < best_total_width_difference)
    {
        best_line_set = current_line_set;
        best_total_width_difference = current_total_width_difference;
    }

    text = original_text;
}

注意我为j选择了最小值5 - 如果最小值为1,它几乎总是获胜,因为它的总宽度差异总是为0.你可能还会考虑包括某种“足够好的“总和上的阈值,这样你就不会多次运行循环来改进已经”足够好“的解决方案。