【问题标题】:find the first longest ascending or descending sub-sequence in a given unsorted sequence by C++用 C++ 在给定的未排序序列中找到第一个最长的升序或降序子序列
【发布时间】:2013-09-03 17:31:29
【问题描述】:

我正在编写一个 C++ 程序,它将查找并打印第一个最长的 整数向量的升序或降序连续子序列。例如, 给定一个带有

的向量
 4, 2, 1, 2, 3, 4, 3, 5, 1, 2, 4, 6, 5

返回 1,2,3,4

我的代码如下:

但是,我不知道如何返回第一个最优解。 例如,上面的序列有 1、2、4、6,也是 4 长。 但是,我们只需要返回 1,2,3,4。

bool findLong(const vector<int> v)
{
  if (v.size() <1)
    return false;
  if (v.size() == 1){
    cout << v[0] << endl;
    return true;
  }
  vector::const_iterator itr_left, itr_right;
  itr_left = v.begin();
  itr_right = v.begin()+1;
  bool ascending_flag ;
  int counter =0;
  if (*itr_right > *(itr_right-1)){
    bool ascending_flag = true;
    ++ascending_counter;    
  } 
  else{
    bool ascending_flag = false;
    ++descending_counter;
  }
  int longest = INT_MIN;
  Vector<int>::iterator longest_left = v.begin(), longest_right =v.begin(); 
  ++itr_right; 
  while (itr_right != v.end())
  {
   if (ascending_flag && *itr_right > *(itr_right-1))
     ++ascending_counter; 

   if (!ascending_flag&& *itr_right < *(itr_right-1))     
     ++descending_counter;       

   if  (ascending_flag&& *itr_right < *(itr_right-1))
   {
     if (ascending_counter > longest )
     {
        longest  = ascending_counter;
        longest_left = itr_left;
        longest_right = itr_right;
    }
    itr_left = itr_right;    
    ascending_counter = 0 ;  
    ascending_flag = false;
  }
  if  (ascending_flag && *itr_right > *(itr_right-1))
  {
    if (descending_counter > longest )
    {
        longest  = descending_counter;
        longest_left = itr_left;
        longest_right = itr_right;
    }       
    itr_left = itr_right;      
    descending_counter = 0 ;
    ascending_flag = true;
  }
  ++itr_right;
 }
 for_each( longest_left , longest_right, print);
 cout << endl;
}

Void print(int i)
{
  cout << i << " , " ;
}

欢迎任何cmets!

谢谢!

【问题讨论】:

  • 1 2 3 4 5 6 是一个较长的子序列。你的意思是 substring 还是 contiguous subsequence 还是你的例子错了?
  • 这是一个基本的动态规划问题(例如适用于许多生物技术问题),因此您可能想研究一下。
  • @IVIAd,是的,它是连续的子序列。对困惑感到抱歉。已更正。

标签: c++ algorithm search


【解决方案1】:

您的代码中有很多错字: 你隐藏了ascending_flag的初始化 您的长度计数似乎不正确。

以下应该可以工作(只要没有两个具有相同值的邻居)。

bool findLong(const vector<int>& v)
{
    if (v.empty())
        return false;
    if (v.size() == 1) {
        cout << v[0] << endl;
        return true;
    }
    vector<int>::const_iterator itr_left = v.begin();
    vector<int>::const_iterator itr_right = v.begin() + 1;
    vector<int>::const_iterator longest_left = itr_left;
    vector<int>::const_iterator longest_right = itr_right;
    bool ascending_flag = (*itr_right > *(itr_right - 1));

    for (++itr_right; itr_right != v.end(); ++itr_right)
    {
        if (ascending_flag ^ (*itr_right < *(itr_right - 1)))
        {
            if (itr_right - itr_left > longest_right - longest_left)
            {
                longest_left = itr_left;
                longest_right = itr_right;
            }
            itr_left = itr_right - 1;
            ascending_flag = !ascending_flag;
        }
    }
    for_each(longest_left, longest_right, print);
    cout << endl;
    return true;
}

【讨论】:

    【解决方案2】:

    以下是一些想法:

    1. 如果函数名为“findX()”,它应该返回 X(例如,指向序列第一个元素的指针或 NULL,或第一个元素的索引或 -1)。如果函数打印 X,则应命名为“printX()”。
    2. 尚不清楚您需要升序还是严格升序(即 (1, 2, 2, 3) 是否适合您)。
    3. 你把事情复杂化了。如果您需要 first 序列,则只需使用反向迭代器并从头到尾,就像这样(我不使用迭代器,但应该清楚如何包含它们):

      int maxLength=1, currentUp=1, currentDown=1; //Last element is sequence of 1 element
      size_t result = v.length()-1;
      for(size_t i = v.length()-1; i!=0; --i){
          if(v[i-1] > v[i]) {
              currentDown++; currentUp=0;
          } else if(v[i-1] < v[i]) {
              currentUp++; currentDown=0;
          } else {
              //Not clear what should happen, change may be needed
              currentUp++; currentDown++;
          }
      
          if(maxLength <= max(currentUp, currentDown)) {
              result = i-1;
              maxLength = max(currentUp, currentDown);
          }
      }
      
      return result;
      

    【讨论】:

      【解决方案3】:

      好吧,对于初学者来说,您的函数将始终返回 true。

      if (v.size() <1)
        return false;
      if (v.size() == 1)
        cout << v[0] << endl;
      return true;
      

      应该是

      if (v.size() <1) {
        return false;
      
      } else if (v.size() == 1) {
        cout << v[0] << endl;
        return true;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多