Click here to Skip to main content
15,559,275 members
Please Sign up or sign in to vote.
2.00/5 (3 votes)
See more:
Hi,

I happened to be asked an question in an interview to get number of occurrences of character in string array is even or odd ? For example we have an array like this.

D,E,X,W,R,X,W,X,Q,O,X

Now how can be find that X is occurring in even times or odd times without using if condition ?
Posted
Comments
PIEBALDconsult 12-Oct-15 17:01pm    
Stupid question.

for , while , switch -- there are several ways to test something, but if would work best here, so why not use it?
The interviewer may have been seeking the ternary operator.
Philippe Mori 14-Oct-15 12:53pm    
Well, it would be stupid if the interviewer want a specific implementation... But otherwise it allows to have an idea on the ability of someone to solve a problem without using trivial solution.

You can use Linq Grouping to do the job


C#
char[] letters = { 'D', 'E', 'X', 'W', 'R', 'X', 'W', 'X', 'Q', 'O', 'X' };
            var characterGroups =
                letters.GroupBy(c => c).GroupBy(g => g.Count() % 2 == 1).ToList();
            var OddGroup = characterGroups.Where(c => c.Key);
            var EvenGroup = characterGroups.Where(c => !c.Key);
            Console.WriteLine("The characters that occur an odd number of times are :");
            foreach (var charGroup in OddGroup.SelectMany(grouping => grouping))
            {
                Console.WriteLine(charGroup.Key);
            }
            Console.WriteLine("The characters that occur an even number of times are :");
            foreach (var charGroup in EvenGroup.SelectMany(grouping => grouping))
            {
                Console.WriteLine(charGroup.Key);
            }
 
Share this answer
 
v2
I propose one line to get whether the number of occurrences of 'X' in the string is odd or even. It uses Linq and a conditional assignment.
C#
string s = "DEXWRXWXQOX";
string result = ((s.Where(c => c == 'X').Count() & 1) == 0) ? "even" : "odd";
 
Share this answer
 
Comments
Matt T Heffron 13-Oct-15 19:12pm    
In an interview, I think I would've proposed a general case solution.
(Actually, I probably would have asked if the interviewer wanted the specific, or general case.)
phil.o 14-Oct-15 1:02am    
It can easily be wrapped in a method accepting the said character as input :)
If you want to return recordset of characters with number of occurences of each of them and information about even/odd, try this:
C#
char[] letters = { 'D', 'E', 'X', 'W', 'R', 'X', 'W', 'X', 'Q', 'O', 'X' };

var result = letters.GroupBy(a=>a)
    .Select(g=>new
        {
            Character = g.Key,
            Count = g.Count(),
            IsEvenOrOdd = g.Count() % 2==0 ? "Even" : "Odd"
        });


Result:
VB
Character Count IsEvenOrOdd
D         1         Odd
E         1         Odd
X         4         Even
W         2         Even
R         1         Odd
Q         1         Odd
O         1         Odd
 
Share this answer
 
Just to be different from C. Pallini and Matt T. Heffron :)

My response to the interviewer's question would be: there is no way to determine the number of objects in a set of objects which match some criterion without a test which compares each member using the criterion, and, that, by definition is a test of equality that requires some form of conditional evaluation, i.e., use of 'if.

And, then, perhaps, I would have written a short piece of code using Linq:
C#
// required
// using System.Linq

private bool IsEven(char letter)
{
    return letters.Count(ch => ch == letter)%2 == 0;
}
 
Share this answer
 
Comments
Krunal Rohit 13-Oct-15 1:02am    
I like it. 5!

-KR
Matt T Heffron 13-Oct-15 14:50pm    
I agree about the response to the interviewer, although an entry level person might not have the confidence to challenge the interviewer.
Otherwise, your solution is good, but it scales at O(N*M) on number of calls to IsEven and the length of the letters collection.
Limiting to uppercase letters:
C#
public static void Main()
  {
    char[] a = { 'D', 'E', 'X', 'W', 'R', 'X', 'W', 'X', 'Q', 'O', 'X' };
    bool [] odd = new bool[26];
    foreach (char c in a)
      odd[c-'A'] = !odd[c-'A'];
    for (int n = 0; n < 26; ++n)
      Console.WriteLine("{0} occurrences number is {1}. ", (char)(n + 'A'), odd[n] ? "odd" : "even");

  }
 
Share this answer
 
v2
Comments
[no name] 12-Oct-15 21:16pm    
Psst. Doesn't work for the letter 'Z'.
CPallini 13-Oct-15 2:48am    
Fixed now, thank you.
Just to be different from CPallini:
C#
public static void Main()
{
  string a = "DEXWRXWXQOX";
  Dictionary<char, bool> odd = new Dictionary<char, bool>();
  foreach (char c in a)
  {
    bool codd;
    odd[c] = odd.TryGetValue(c, out codd) && !codd;
  }
  foreach (char c in odd.Keys)
    Console.WriteLine("{0} occurrences number is {1}. ", c, odd[c] ? "odd" : "even");
}

OR
C#
private static readonly string[] EO = new string[] { "even", "odd" };
public static void Main()
{
  string a = "DEXWRXWXQOX";
  Dictionary<char, int> counts = new Dictionary<char, int>();
  foreach (char c in a)
  {
    int n;
    counts.TryGetValue(c, out n); // you don't HAVE to use the returned Boolean ;-)
    // if there was no existing entry for c in counts then n has been set to 0
    counts[c] = n + 1;
  }
  foreach (char c in counts.Keys)
    Console.WriteLine("{0} occurrences number is {1}. ", c, EO[counts[c] & 1]);  // L.S.B. is 1 if odd
}
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900