【问题标题】:Variant of the 2-sum algorithm with a range of sums具有一系列和的 2-sum 算法的变体
【发布时间】:2016-12-22 15:20:42
【问题描述】:

问题陈述如下:

这个问题的目标是实现 2-SUM 算法的一个变体。

该文件包含一百万个整数,包括正数和负数(可能有一些重复!)。这是您的整数数组,文件的第 i 行指定数组的第 i 个条目。

您的任务是计算区间 [-10000,10000](含)内的目标值 t 的数量,使得输入文件中存在满足 x+y=t 的不同数字 x,y。

写出你的数字答案(0 到 20001 之间的整数)。

我实现了一个幼稚的解决方案:

#include <iostream>
#include <fstream>
#include <unordered_set>
#include <vector>
#include <algorithm>

#define FILE "2sum.txt"
#define LEFT -10000
#define RIGHT 10000

using namespace std;

class cal_2sum{
    int count;
    unordered_set<long> hashT;
    vector<long> array;

public:
    cal_2sum(){
        count = 0;  
    }
    int getCount(){
        return this->count;
    }
    int calculate(string filename,int left, int right){
        ifstream file(filename);

        long num;
        while(file>>num){
            hashT.insert(num);

        }
        for(auto it = hashT.begin(); it != hashT.end(); ++it)
            array.push_back(*it);
        sort(array.begin(),array.end());

        for(long target = left; target<=right; target++){
            bool found = false;
            for(auto it = array.begin(); it != array.end(); ++it){
                long otherHalf = target - (*it);
                auto verdict = hashT.find(otherHalf);
                if(verdict != hashT.end() && (*verdict) != (*it)){
                    found  = true;
                    break;
                }
            }
            if(found == true)
                count++;
            cout<<count<<endl;
        }
    }

};


int main(){
    cal_2sum res;
    res.calculate(FILE,LEFT,RIGHT);
    cout<<res.getCount()<<endl;

    return 0;
}

它给出了正确的答案,但是它太慢了。我该如何改进解决方案。 输入数字在 [-99999887310 范围内 ,99999662302].

【问题讨论】:

  • 你知道整数x和y的范围吗?如果它们

标签: arrays sorting hashtable unordered-set


【解决方案1】:

来源 2sum.c:

#include <stdio.h>
#include <strings.h>

#define MAXVAL 10000

int main(int argc, char **argv) {
  // init vars
  int i, t, rc = 0;
  unsigned arr[2 * MAXVAL + 1], *p0 = arr + MAXVAL;
  bzero(arr, sizeof(arr));

  FILE *f = fopen(argv[1], "r");
  if(f == NULL)
    return -1; // unable to open file

  char buf[100];
  while(fgets(buf, sizeof(buf), f))
    p0[atoi(buf)]++;

  t = atoi(argv[2]); // Target sum

  for(i = -MAXVAL; i <= MAXVAL; i++)
    rc += p0[i] * p0[t - i];

  printf("Combinations: %d\n", rc >> 1);
  return fclose(f);
}

测试文件2sum.txt:

5
5
10
10
1
-5

运行示例:

$ ./a.out 2sum.txt 0
Combinations: 2

$ ./a.out 2sum.txt 15
Combinations: 4

$ ./a.out 2sum.txt 13
Combinations: 0

对于大范围,将数组 arr 更改为哈希表。

【讨论】:

  • 如果你仍然活跃,你能帮我理解吗,1.$ ./a.out 2sum.txt 15 = Combinations: 4我不知道这是怎么回事,因为你有 (10,5) 或 (5,10) 2. 在你的代码,t 应该在 -10000 到 10000 之间,但是你已经在命令行 t = atoi(argv[2]); // Target sum 上设置了它的值,然后将 i 的值更改为 -10000 到 10000 之间希望我没有遗漏什么。
  • 1.我的文件中有 10 个中的两个和 5 个中的两个,因为您说:(可能有一些重复!),并且需要计算所有可能的组合。所以,我的 4 种组合是:(10a 5a)、(10b 5a)、(10a 5b)(10b 5b)。如果您只需要计算一些数字,请更改“p0[atoi(buf)]++;”行到“p0[atoi(buf)] = 1;”。如果你想限制目标 - 只需添加 if() 语句,我认为这很容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-11
  • 2012-08-09
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
相关资源
最近更新 更多