【问题标题】:getting profit in array without using loops在不使用循环的情况下在数组中获利
【发布时间】:2018-06-02 12:51:21
【问题描述】:

我在 tradeTest.cpp 中有类似的东西

int main() {
    vector<int> prices{38, 28, 30, 38, 34};

    int profit = bestProfit(prices.begin(), prices.end());

    if (profit == 10) {
        cout << "Profit of 10 is correct\n";
    } else {
        cout << "Profit of " << profit << " is incorrect\n";
    }
}

目前在 trade.h 中

template <class Iterator>
int Profit (Iterator begin, Iterator end)
{

}

我想做的是低买高卖,没有回头的可能。

感谢您的主题。

【问题讨论】:

  • 如果它们已排序。那么低价是*begin,高价是*(end - 1)
  • @Carcigenicate 抱歉,我编辑了我的意思是卖高的问题。谢谢
  • @LokiAstari 他们没有排序
  • 你用过 lambda 和排序算法吗
  • 你可以回去了。没有什么能阻止您复制开始迭代器并进行多次迭代。

标签: c++ c++11


【解决方案1】:

添加int max = 0 参数是一种简单的方法:

template <class Iterator>
int bestProfit (Iterator begin, Iterator end, int max = 0)
{
    if(begin==end)
    {
        return max;
    }else
    {
        int p = *std::max_element(begin+1, end) - *begin;
        max = std::max(max, p);        
        return bestProfit(begin+1, end, max);
    }

}

int main() {
    vector<int> prices{28, 18, 20, 26, 24};

    int profit = bestProfit(prices.begin(), prices.end());

    if (profit == 8) {
        cout << "Profit of 8 is correct\n";
    } else {
        cout << "Profit of " << profit << " is incorrect\n";
    }
}

【讨论】:

  • 正如我在另一个答案中所说,排序并不能解决问题。
  • 这是错误的,利润是 10 而应该是 26-18 = 8
  • @CrisLuengo 这种排序允许您获得最高和最低值。排序是正确的解决方案
  • @justewe3 28 是最高的,18 是最低的也许你应该告诉我们 26 是什么
  • @JakeFreeman 问题是你不能按时回去。我在问题中提到了它。所以一旦你买了你必须在未来卖掉(你买的数字后面的数字(
【解决方案2】:

这是一个简单的神圣和征服算法。而且我认为您还没有正确描述问题,对数组进行排序是错误的。因为 18-28 将是最大值,但如果阵列处于该顺序,您不能在 18 买入并在 28 卖出

【讨论】:

  • 也确实在询问堆栈溢出之前打开你的算法书。这是cs类大学在算法中的经典问题
  • 好好生活吧。
【解决方案3】:

正如我在 cmets 中建议的那样,您可能想做这样的事情。抱歉,我现在无法测试,无法保证!

template <class Iterator>
int bestProfit (Iterator begin, Iterator end)
{
  int profit = 0;
  for(;begin!=end; ++begin){
    int p = *std::max_element(begin+1, end) - *begin;
    profit = std:max(profit, p);
  }
  return profit;
}

正如评论中的某处所建议的那样,使用递归函数也可以非常优雅。

上面的代码可能应该跳过最后一次循环迭代,想想看。如果两个输入迭代器相同,std::max_element 返回什么?

编辑:

您已经有了一个可行且可接受的答案,但为了完整起见(我想我很固执)这是我的递归函数版本。这没有任何显式循环,但std::max_element内部有一个循环,递归函数是一种编写循环的方式。没有循环就无法访问向量或列表中的所有元素!

#include <vector>
#include <algorithm>
#include <iostream>

// Look mama! No `for`!
template <class Iterator>
int bestProfit (Iterator begin, Iterator end)
{
  int buy = *begin;
  ++begin;
  if (begin == end) return 0; // no profit to be had
  int sell = *std::max_element(begin, end);
  int profit = sell - buy; // max profit if we buy now
  return std::max(profit, bestProfit(begin, end)); // will we do better if we wait?
}

int main() {
  std::vector<int> prices1{38, 28, 30, 38, 34};
  if (bestProfit(prices1.begin(), prices1.end()) != 10)
    std::cout << "bad 1!\n";

  std::vector<int> prices2{1, 2, 3, 4, 5, 0};
  if (bestProfit(prices2.begin(), prices2.end()) != 4)
    std::cout << "bad 2!\n";

  std::vector<int> prices3{2, 3, 1, 4, 5, 0};
  if (bestProfit(prices3.begin(), prices3.end()) != 4)
    std::cout << "bad 3!\n";

  std::vector<int> prices4{0, 1, 2, 5, 4, 3};
  if (bestProfit(prices4.begin(), prices4.end()) != 5)
    std::cout << "bad 4!\n";

  std::vector<int> prices5{100, 200, 0, 1, 3};
  if (bestProfit(prices5.begin(), prices5.end()) != 100)
    std::cout << "bad 5!\n";

  std::vector<int> prices6{100, 200, 0, 101, 30};
  if (bestProfit(prices6.begin(), prices6.end()) != 101)
    std::cout << "bad 6!\n";
}

【讨论】:

  • 我试过了,但我收到了这个错误error: cannot convert ‘__gnu_cxx::__normal_iterator&lt;int*, std::vector&lt;int&gt; &gt;’ to ‘int’ in initialization 它指向*begin; 知道如何解决它吗?
  • 啊,有道理,对不起,我会解决的。它需要取消引用。
  • 我认为这取消了最后一次循环迭代中的结束迭代器。我需要一个更好的屏幕才能做到这一点:/
  • 我刚刚意识到您正在使用 for 循环,问题是 不使用命令式循环
  • 感谢您的回答,虽然效果很好,但它使用了 for 循环
猜你喜欢
  • 2019-12-01
  • 2015-03-06
  • 2013-05-19
  • 1970-01-01
  • 2011-04-26
  • 2020-02-26
  • 1970-01-01
  • 2023-02-05
  • 2011-07-25
相关资源
最近更新 更多