算术序列 - 检查

时间:2015-10-12 16:23:53

标签: c++ algorithm math

检查是否可以从指定的数字序列创建算术序列的最有效方法是什么?

目前我对序列进行排序,然后执行此操作:

#include<bits/stdc++.h>
using namespace std;

static bool sort_using_greater_than(float u, float v)
{
return u > v;
}


int main()
{
int licznik=0, i=0;
double number[100000];
while(~scanf("%f", &number[i]))
{
     i++;
     licznik++;
}
 sort(number,number+100, sort_using_greater_than);

for(int i = 1; i < licznik-1; i++)
{
    if(number[i] - number[i+1] != number[0] - number[1])
    {
        puts("NO");
        return 0;
    }
}
puts("YES");

}

进行测试:

  1. 1.0 5.0
  2. 我的代码返回YES,为什么?

    enter code here
    double search_min(double tab[], int n)
    {
    double min = tab[0];
    for(int i = 1; i < n; i++)
    {
        if(min > tab[i])
            min = tab[i];
    return min;
    }
    

    而且,我怎样才能找到两个最小的元素?

2 个答案:

答案 0 :(得分:3)

问题尚不清楚,但如果它意味着“检查给定的数字是否可以从一个算术序列重新排列”,那么就没有必要进行排序。

  • 找到最小的元素,在O(N)中,让a;

  • 找到第二个最小的,在O(N)中,让b;

  • 清除O(N)中的N位数组;

  • 对于每个数字c,计算(c - a)/(b - a);如果这不是范围[0,n-1]中的整数,则答案为否。否则,将该位设置为该索引(在每个元素的O(1)中完成);

  • 检查所有位是否已在O(N)中设置。

整个过程需要时间O(N)。

答案 1 :(得分:-1)

O(n)是您必须检查每个元素的最佳选择。

我已经实现了Yves Daoust的算法(有一些小的优化)以及你自己的C ++ 14标准代码。

这是你的:

int main(int argc, char* argv[]) {

    if(argc == 1) return 0;

    //Copy command args to vector of strings.
    std::size_t number_count = argc - 1;
    std::vector<std::string> cmd_args(number_count);
    std::copy(argv + 1, argv + argc, cmd_args.begin());

    //Copy convert vector of strings to vector of ints.
    std::vector<int> values(number_count);
    auto v_begin = values.begin();
    for(auto s : cmd_args) {
        (*v_begin) = std::stoi(s);
        ++v_begin;
    }

    //Sort values in ascending order.
    std::sort(values.begin(), values.end());

    //Get smallest two values.
    std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));

    //Calculate differences between each successive number
    std::vector<int> differences(values.size() - 1);
    for(std::size_t i = 0; i < values.size() - 1; ++i) {
        differences[i] = std::abs(values[i] - values[i + 1]);
    }

    //All values in differences must be the same.
    if(std::all_of(differences.cbegin(), differences.cend(), [=](int i) { return i == *differences.cbegin(); })) {
        std::cout << "YES\n";
    } else {
        std::cout << "NO\n";
    }

    return 0;
}

这是Yves Daoust的算法:

int main(int argc, char* argv[]) {
    if(argc == 1) return 0;

    //Copy command args to vector of strings.
    std::size_t number_count = argc - 1;
    std::vector<std::string> cmd_args(number_count);
    std::copy(argv + 1, argv + argc, cmd_args.begin());

    //Copy convert vector of strings to vector of ints.
    auto v_begin = values.begin();
    for(auto s : cmd_args) {
        (*v_begin) = std::stoi(s);
        ++v_begin;
    }

    //Sort values in ascending order.
    std::sort(values.begin(), values.end());

    //Get smallest two values.
    std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));

    std::vector<bool> bits(values.size());

    bool result = true;

    int smallest_diff = (two_smallest_values.second - two_smallest_values.first);
    for(auto v : values) {
        int numerator = v - two_smallest_values.first;
        int denominator = smallest_diff;
        if(numerator % denominator != 0) {
            result = false;
            break;
        }
        std::size_t i = numerator / denominator;
        if(i < 0 || i >= values.size()) {
            result = false;
            break;
        }
        bits[i] = true;
    }

    if(result == false) {
        std::cout << "NO\n";
        return 0;
    }        

    //Convert vector of bools (bit-packed) to an unsigned int.
    unsigned long long bits_value = 0;
    unsigned long long i = 0;
    for(auto b : bits) {
        bits_value |= (b << i++);
    }

    //Optimization: Single calculation to determine if all bits are set:
    if(std::abs(bits_value - (std::pow(2.0, bits.size()) - 1) < 0.01)) {
        std::cout << "YES\n";
    } else {
        std::cout << "NO\n";
    }

    return 0;
}