如何验证文件中的给定数字是否在算术级数中?

时间:2017-09-25 16:34:42

标签: c++

基本上我想要做的是验证数字:180 30 80 280 130 330 230 30 30 330 80是否在算术级数并找到比率。我尝试使用以下算法,但即使我在行中插入35(这是不正确的),答案是50而不是NO。

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    int x, fr[1000]={0} ,r=0 , ok=0, i, v[100], j=0;
    ifstream f("bac.in");
    while(f>>x)
        fr[x]++;
    for(i=0; i<1000; i++)
    {
        if(fr[i]!=0) // I search for the first frequency and only then start to count 
        ok=0;
        else ok=1;

    if(ok==0)
        r++; // ratio
        else {v[j++]=r; r=0;} // if another frequency was found, ratio is reseted
    }

    for(i=0;i<j-1;i++) // i verify if every ratio is equal in this for
    {
        if(v[i]==v[i+1])
            ok=1;
        else ok=0;
    }
    if(ok==1)
        cout<<++v[i];
        else cout<<"NO";
    f.close();
}

我的想法是在频率之间找到0的数字并将其计算为比率并将其放入数组中,我将验证比率是否相等。如果我遗漏了任何信息,请告诉我。 它必须以有效的方式完成,因此将数字放入数组,对其进行排序,删除加倍的数字,并且只有在找到比率(如果有的话)之后才会讨论。

3 个答案:

答案 0 :(得分:1)

您可以使用std::set来完成此操作。设置保证没有重复,并保持您的数据排序!这意味着您只需要将所有内容都放入集合中,然后迭代一次以检查差异。

插入套装会花费O(log(n)),我们会n这样做,以便O(nlog(n))成为O(n)。然后,我们循环设置以检查我们是否有进展,以便另一个O(nlog(n) + n) = O(nlog(n))给我们复杂性#include <iostream> #include <set> #include <iterator> int main() { std::set<int> values; int x; while (std::cin >> x) { //replace cin with your file handler values.insert(x); } int difference = 0; bool good = true; for(auto it = values.begin(); it != values.end() && std::next(it) != values.end(); it++) { if(!difference) difference = *it - *std::next(it); else if(difference != *it - *std::next(it)) good = false; } if(good) { std::cout << "We have a progression!" << std::endl; } else { std::cout << "No go on the progression." << std::endl; } return 0; } 。这对你来说够快吗?

@Component
public class ConfigurationManagerComponent{
  @Value("conf.username")
  private String userName;
  @Value("conf.email");
  private String email;
  /*
   * All your attributes
  */
  //getters and setters
  public String getUserName(){
    return this.userName;
  }
  public void setUserName(String userName){
   // first set the value to this class (component)
   this.userName=userName;
   //second save this value in the properties file
   //a specific method you have to implement
    saveproperties("conf.username",userName); 
  }
  /*
   * Do like this for all your getters and setters
  */ 
}

在行动here中查看(意外链接)。

答案 1 :(得分:0)

您的错误位于最后一个循环中,该循环应为:

bool ok = true;
for (int i = 0; i < j - 1; ++i) // i verify if every ratio is equal in this for
{
    if (v[i] != v[i+1]) {
        ok = false;
        break;
    }
}

ok = (j == 0 || std::all_of(v, v + j, [&](int e) { return e == v[0]; }));

固定代码:

std::vector<int> values {180, 30, 80, 280, 130, 330, 230, 30, 30, 330, 80 };
int fr[1000]={0};
for (auto e : values)
    fr[e]++;
int j = 0;
int v[100];
int r = 0;
for(int i=0; i<1000; i++)
{
    if(fr[i] == 0)
        r++; // ratio
    else {
        v[j++]=r;
        r=0;
    } // if another frequency was found, ratio is reseted
}

bool ok = true;
for (int i = 1; i < j - 1; ++i) // i verify if every ratio is equal in this for
{
    if (v[i] != v[i+1]) {
        ok = false;
        break;
    }
}
if(ok==1)
    std::cout << v[1] + 1;
else
    std::cout<<"NO";

Demo

答案 2 :(得分:0)

以下是O(n)解决方案:

  • 迭代查找最小,第二小和最大元素的列表。 (它通过三次单独的迭代来完成,但它可以是一个带有更多代码的循环。)
  • 表示这些 x 0 x 1 x n ,假设有一个算术级数我们现在可以计算出差异( c = x 1 - x 0 )和元素总数( n +1 =( x n - < EM> X <子> 0 )/ C 的)。
  • 我们创建一个长度为 n +1的布尔数组,并开始标记当前元素。如果不属于这种模式,我们会立即返回false。最后,我们检查所有元素是否都标记为false。

顺便说一句,我认为@ scohe001的答案会更好。它稍慢,但更明显的是它是正确的 是非常重要的,除非你已经尝试过并发现它确实太慢了。如果您只处理数十万或更少的元素,则时间差异不太可能显着,特别是如果您还必须从文件中读取元素,这可能会慢得多比这个阶段。

#include <iostream>
#include <vector>
#include <limits>
#include <boost/dynamic_bitset.hpp>
#include <algorithm>
#include <stdlib.h>

int conditionalMin(const std::vector<int>& numbers, int lowerBound)
{
    int result = std::numeric_limits<int>::max();
    for (int x : numbers) {
        if (x < result && x > lowerBound) {
            result = x;
        }
    }
    return result;
}

bool isArithmeticSet(const std::vector<int>& numbers)
{
    // Look for smallest, second smallest, and largest numbers
    int x0 = *std::min_element(numbers.begin(), numbers.end());
    int x1 = conditionalMin(numbers, x0);
    int xn = *std::max_element(numbers.begin(), numbers.end());

    // Find which elements are present (exit early if any inappropriate elements)
    int sequenceCount = (xn - x0) / (x1 - x0) + 1;
    boost::dynamic_bitset<> present(sequenceCount);
    for (int x : numbers) {
        div_t divResult = div(x - x0, x1 - x0);
        if (divResult.rem != 0 || divResult.quot < 0 || divResult.quot > sequenceCount) {
            return false;
        }
        present[divResult.quot] = true;
    }

    // Are all the required elements present?
    return present.all();
}


int main() {
    std::vector<int> numbers = {180, 30, 80, 280, 130, 330, 230, 30, 30, 330, 80 };

    std::cout << "is an arithmetic set: " << isArithmeticSet(numbers) << "\n";

    return 0;
}