【问题标题】:Effectively finding number sequences in vectors?有效地找到向量中的数字序列?
【发布时间】:2016-12-19 01:42:31
【问题描述】:

我有以下向量:

std::vector<int> ExampleVector {10, 2, 5, 1, 8, 20};

我需要找到 3 个元素(A、B、C),其中:

1) A > B

2) (A + B) > C

3) A

在ExampleVector的情况下,10 5 8 满足上述条件。

我最初的尝试使用了多个具有给定条件的迭代器:

int main()
{
  for(auto first_iterator = A.begin(); first_iterator != A.end(); first_iterator++)
  {
    for(auto second_iterator = first_iterator() + 1; second_iterator != A.end(); second_iterator++)
    {
        for(auto third_iterator = second_iterator() + 1; third_iterator != A.end(); third_iterator++)
        {
            bool condition_1 {(*first_iterator + *second_iterator) > *third_iterator};
            bool condition_2 {(*second_iterator + *third_iterator) > *first_iterator};
            if(condition_1 && condition_2)
            {
                return 1;
            }
        }
    }
  }
  return 0;
}

这有效地导致:

iterator         cycle1  cycle2  cycle3  cycle4  cycle5  cycle6  cycle7 ... N
first_iterator:    10     10       10      10      10     10       10
second_iterator:   2      2        2       2       5      5        5
third_iterator:    5      1        8       20      1      8        20

显然这是非常低效的!

我可以使用更好的方法来解决此类问题吗?

【问题讨论】:

  • 你试过对向量进行排序吗?

标签: c++ loops vector time-complexity


【解决方案1】:

你首先需要问问自己是否可以改进

重新调整您的内容,使其更易于阅读...

1) B < A && B < C
2) (B + A) > C
3) (B + C) > A 

如果仔细观察,如果 B == 0,A > C 和 C > A,这是不可能的。

【讨论】:

    【解决方案2】:

    编辑

    vector<vector<double>> store = vector<vector<double>>(0);    
    for (int i = 0; i < theVect.size(); ++i) {
            for (vector<double> v : store) {
                if (v.size() == 1) {
                    if (v[0] > B) {
                        v.push_back(b)
                        }
                } 
                else if (v.size() == 2) {
                if (A + B > C && A < B + C) {
                    return true;
                }
            }
            store.push_back(vector<double> {theVect[i]});
        }
    

    这是正确的答案。 --> 需要一次总迭代我相信这是 N^2 次,而您的答案是 N^3 次。 (最坏的情况)

    *技术上比 N^3 时间少一点,但足够接近。

    ** 下面是原始帖子,上面是编辑(供将来的观众使用)

    哇,这是一些令人费解的编码。

    我相信你的想法是对的,但你的编码风格真的很奇怪。更易读的方法是简单地使用 for 循环。

    bool condition1 = false;
    bool condition2 = false; 
    bool condition3 = false;
    
    for (int x = 0; x < theVector.size(); ++x) {
       for (int y = x + 1; y < theVector.size(); ++y) {
            for (int z = y + 1; z < theVector.size(); ++z) {
               if (!condition1) {
                   condition1 = conditionChk1(theVector[x], theVector[y], theVector[z]);
               }
               if (!condition2) {
                   condition2 = conditionCk2(theVector[x], theVector[y], theVector[z]);
               }
               if (!condition3) {
                   condition3 = conditionCk3(theVector[x], theVector[y], theVector[z]);
               }
            }
        }
    }
    

    conditionCk 方法接受双精度值并根据它们是否满足要求返回一个布尔值。这本质上是您的方法,只是不那么复杂。

    【讨论】:

    • 另外,您可以选择不编写单独的条件方法,而只需编写另一个 if 语句然后为真。 (这只是美学上更好)
    • 我和你的唯一区别在于我的循环使用了迭代器。否则,它的方法完全相同。我使用迭代器循环,因为可能使用 std::advance 或 std::next 可以降低运行时间复杂度
    • For 循环与迭代器非常相似,对于向量而言,这不会显着提高性能。
    • 您的问题是否要求每个元素都井井有条?如果不是,我们的实现都不正确。
    • 使用 std::next 或 std::advance (而不是嵌套循环)会提高性能。不,在这种情况下,我只需要确定序列的存在(因此返回 1)。
    猜你喜欢
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 2015-11-17
    • 2020-12-15
    • 2017-06-19
    相关资源
    最近更新 更多