更有效的方法来找到向量中的连续数字?

时间:2017-06-01 22:35:20

标签: c++ algorithm vector

我需要编写一个程序来按行的顺序打印文件中特定单词的行号。该程序的示例输出将是:

 Hello 1, 3, 5-6, 8, 10-15.
// 5-6 represents 5, 6 (consecutive numbers)

行号存储在已排序的vector<int>中,没有重复项。我已经创建了一个解决方案,但我的直觉告诉我,我可以做得更好。我会很感激一些反馈。此外,以下代码仅处理行号。这个词可以在另一种方法中找到。

void IndexPager::createLines(vector<int>& vec, string& line)
{
  int start = *vec.begin(), end = -1, offset = 0; // initial offset to start

  for (vector<int>::const_iterator itr = vec.begin();
       itr != vec.end() + 1; itr++)
  {
    if (*itr == start + offset && itr != vec.end())
    {
      end = *itr;
      ++offset;
    } // check if line numbers are consecutive and not reading at end of vector
    else // not consecutive
    {
      if ((end != -1) && (end != start))
      {
        line.append(intToString(start) + "-");
        line.append(intToString(end));
      } // if there existed consecutive numbers, display with dash
        // must be difference of at least 1
      else // else, there were no consecutive numbers
        line.append(intToString(start));

      if (itr != vec.end()) // check if not at end of vector
        line.append(", ");
      else // reached end of vector
        line.append(".");

      start = *itr; // set start to next line number. Soft reset.
      offset = 1; // change default offset to 1. 0 for first case.
      end = -1;
    } // not consecutive
  } // Get all line numbers and format for proper output
} // createLines()

1 个答案:

答案 0 :(得分:0)

一些观察结果。

  1. 你假设矢量长度是> 0
  2. vec.end()+ 1可能无法提供您期望的结果,具体取决于矢量实现。
  3. 在循环体的开始处递增itr而不是在结束处用于解决这两个问题。

    关于效率,您可以尝试将“start + offset”替换为“next”

    void IndexPager::createLines(vector<int>& vec, string& line)
    {
        int start,end,next;
        vector<int>::const_iterator itr = vec.begin();
        next=end=start=*itr;
        while(itr!=vec.end())
        {
            ++itr;
            end=next++;
            if(itr==vec.end()||next!=*itr)
            {
                // break in consecutive sequence
                line.append(intToString(start));
                if(end!=start){
                    line.append("-");
                    line.append(intToString(end));
                }
                if(itr!=vec.end())
                {
                    line.append(", ");
                }
                next=end=start=*itr;
            }
        } // Get all line numbers and format for proper output
        line.append(".");
    } // createLines()
    

    itr仍然每次迭代检查vec.end()三次,所以你可能想要在循环结束时重复break-in-sequence部分并使用normal(auto i:vec)代替,但是说编译器优化可能会消除重复