0

For this question, "Given an array where every element occurs three times, except one element which occurs only once. Find the element that occurs once. "

I tried the code given at http://www.geeksforgeeks.org/find-the-element-that-appears-once/. But, I get an incorrect answer of 1 when input is 3,3,1,3,6,1,6,7,1.

Please help me in finding the mistake I'm doing.

#include<iostream>

using namespace std;

int getSingleOccurrence(int nArray[9], int n){
int ones = 0, twos=0;
int common_bit_mask=0;

for(int i=0;i<n;i++){
    twos|= ones & nArray[i];
    ones^=nArray[i];
    common_bit_mask = ~(ones & twos);
    ones&=common_bit_mask;
    twos&=common_bit_mask;
}
return ones;
}


int main(){
   int nArray[]={3,3,1,3,6,1,6,7,1};
   cout<<getSingleOccurrence(nArray,9);
   return 0;
}
James M
  • 18,506
  • 3
  • 48
  • 56
GBSE
  • 17
  • 2
  • 4
    C or C++? The solutions could be vastly different depending on language. For example, in C++ *I* would use [`std::unordered_multiset`](http://en.cppreference.com/w/cpp/container/unordered_multiset). – Some programmer dude Aug 08 '14 at 11:14
  • 2
    Count the 6s. One or three? – n. m. could be an AI Aug 08 '14 at 11:18
  • 5
    Your input data is invalid so you won't get a meaningful result even if the code is correct. – Paul R Aug 08 '14 at 11:18
  • @JoachimPileborg the complexity with unordered sets is quadratic in the worst case. Since it's a contrived unrealistic problem, it ought to deal with contrived unrealistic input. – n. m. could be an AI Aug 08 '14 at 11:23
  • 1
    Per `using` and `cout` it is C++, but the algorithm as proposed is language agnostic. Perhaps you should clarify if you need this, or if a C++ *only* solution is acceptable. – Jongware Aug 08 '14 at 11:36
  • Removed C tag since the code example given is C++. – James M Aug 08 '14 at 14:16
  • I know you have your solution, but just wanted to say that this is a neat little problem. It took me awhile and to see why it works and I can't say the comments at the link with the original code were especially helpful, so I'll add my take. The algorithm is essentially binary addition. What it's doing is adding 32 numbers (one for each bit) under modulo 3. The `ones` is the 1s place, the `twos` is the 2s place, when the number becomes 3 (binary 11) it resets is to zero (3 mod 3 is zero). So bits bit's with 0 mod 3 occurrences disappear, while bits with 1 mod 3 occurrences remain in place. – Apriori Aug 08 '14 at 14:37

2 Answers2

6

This is the sort of stupid trickiness which has no use in practical code. In this case, the algorithm (explicitly) only works if all elements are present 3 times, except one which is present once. If any objects are present an even number of times, it will fail. In your input, 6 is present twice, so it fails.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

It doesn't work if you have two of one number. And you have two 6's.

Also, note you shouldn't specify the length of the array in the method parameter.

This works: ideone

#include <stdio.h>

int getSingleOccurrence(int nArray[], int n){ //note no array length here
  int ones = 0, twos=0;
  int common_bit_mask=0;
  int i;

  for(i=0;i<n;i++){
    twos|= ones & nArray[i];
    ones^=nArray[i];
    common_bit_mask = ~(ones & twos);
    ones&=common_bit_mask;
    twos&=common_bit_mask;
  }
  return ones;
}


int main(){
   int nArray[]={3,3,1,3,6,1,6,7,1,6};
   int result = getSingleOccurrence(nArray,10);
   printf("Result %d", result);
   return 0;
}
weston
  • 54,145
  • 21
  • 145
  • 203