Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding an integer sum in an array of 1 000 000

Tags:

c#

sum

Given a large list of integers (more than 1 000 000 values) find how many ways there are of selecting two of them that add up to 0.... Is the question

What I have done is create a positive random integer list:

Random pos = new Random();
int POSNO = pos.Next(1, 1000000);
lstPOS.Items.Add(POSNO);
lblPLus.Text = lstPOS.Items.Count.ToString();
POSCount++;

And created a negative list:

Random neg = new Random();
int NEGNO = neg.Next(100000, 1000000);
lstNEG.Items.Add("-" + NEGNO);
lblNegative.Text = lstNEG.Items.Count.ToString();
NegCount++;

To do the sum checking I am using:

foreach (var item in lstPOS.Items)
{
    int POSItem = Convert.ToInt32(item.ToString());
    foreach (var negItem in lstNEG.Items)
    {
        int NEGItem = Convert.ToInt32(negItem.ToString());
        int Total = POSItem - NEGItem;
        if (Total == 0)
        {
            lstADD.Items.Add(POSItem + "-" + NEGItem + "=" + Total);
            lblAddition.Text = lstADD.Items.Count.ToString();
        }
    }
}

I know this is not the fastest route. I have considered using an array. Do you have any suggestions?

like image 563
Greg Adler Avatar asked Nov 05 '15 04:11

Greg Adler


People also ask

How to find the sum of all highest occurring elements in array?

Given an array of integers containing duplicate elements. The task is to find the sum of all highest occurring elements in the given array. That is the sum of all such elements whose frequency is maximum in the array. Input : arr [] = {1, 1, 2, 2, 2, 2, 3, 3, 3, 3} Output : 20 The highest occurring elements are 3 and 2 and their frequency is 4.

How to sum all values of an array in C++?

We shall use a loop and sum up all values of the array. Algorithm. Let's first see what should be the step-by-step procedure of this program −. START Step 1 → Take an array A and define its values Step 2 → Loop for each value of A Step 3 → Add each element to 'sum' variable Step 4 → After the loop finishes, display 'sum' STOP

What is the sum of all 3's and 2's in the array?

That is the sum of all such elements whose frequency is maximum in the array. Input : arr [] = {1, 1, 2, 2, 2, 2, 3, 3, 3, 3} Output : 20 The highest occurring elements are 3 and 2 and their frequency is 4. Therefore sum of all 3's and 2's in the array = 3+3+3+3+2+2+2+2 = 20.

What is the sum of all even frequencies in an array?

That is the sum of all such elements whose frequency is even in the array. Input : arr [] = {1, 1, 2, 2, 3, 3, 3} Output : 6 The even occurring element are 1 and 2 (both occur two times).


1 Answers

Let's see; your array is something like this:

  int[] data = new int[] {
    6, -2, 3, 2, 0, 0, 5, 7, 0, -2
  };

you can add up to zero in two different ways:

  1. a + (-a) // positive + negative
  2. 0 + 0 // any two zeros

in the sample above there're five pairs:

  -2 + 2 (two pairs): [1] + [3] and [3] + [9]
   0 + 0 (three pairs): [4] + [5], [4] + [8] and [5] + [8]

So you have to track positive/negative pairs and zeros. The implementation

 Dictionary<int, int> positives = new Dictionary<int, int>();
 Dictionary<int, int> negatives = new Dictionary<int, int>(); 
 int zeros = 0;

 foreach(var item in data) {
   int v;

   if (item < 0) 
     if (negatives.TryGetValue(item, out v))     
       negatives[item] = negatives[item] + 1;
     else
       negatives[item] = 1;  
   else if (item > 0) 
     if (positives.TryGetValue(item, out v))     
       positives[item] = positives[item] + 1;
     else
       positives[item] = 1;  
   else
     zeros += 1;
 } 

 // zeros: binomal coefficent: (2, zeros)
 int result = zeros * (zeros - 1) / 2;

 // positive/negative pairs
 foreach (var p in positives) {
   int n;

   if (negatives.TryGetValue(-p.Key, out n)) 
     result += n * p.Value; 
 } 

 // Test (5)
 Console.Write(result); 

Note, that there's no sorting, and dictionaries (i.e. hash tables) are used for positives and negatives so the execution time will be linear, O(n); the dark side of the implementation is that two additional structures (i.e. additional memory) required. In your case (millions integers only - Megabytes) you have that memory.

Edit: terser, but less readable Linq solution:

  var dict = data
    .GroupBy(item => item)
    .ToDictionary(chunk => chunk.Key, chunk => chunk.Count());

  int result = dict.ContainsKey(0) ? dict[0] * (dict[0] - 1) / 2 : 0;

  result += dict
    .Sum(pair => pair.Key > 0 && dict.ContainsKey(-pair.Key) ? pair.Value * dict[-pair.Key] : 0);
like image 190
Dmitry Bychenko Avatar answered Sep 24 '22 08:09

Dmitry Bychenko