Variant of the 2-sum algorithm with a range of sums

≯℡__Kan透↙ 提交于 2019-12-11 05:34:13

问题


The problem statement is as follows:

The goal of this problem is to implement a variant of the 2-SUM algorithm.

The file contains 1 million integers, both positive and negative (there might be some repetitions!).This is your array of integers, with the ith row of the file specifying the ith entry of the array.

Your task is to compute the number of target values t in the interval [-10000,10000] (inclusive) such that there are distinct numbers x,y in the input file that satisfy x+y=t.

Write your numeric answer (an integer between 0 and 20001).

I have implemented a naive solution:

#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;
}

It gives the correct answer, but, it is too slow. How can i improve the solution. The input numbers are in the range [-99999887310 ,99999662302].


回答1:


Source 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);
}

Test file 2sum.txt:

5
5
10
10
1
-5

Run examples:

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

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

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

For huge range, change array arr to hashtable.



来源:https://stackoverflow.com/questions/38971693/variant-of-the-2-sum-algorithm-with-a-range-of-sums

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!