-4
\$\begingroup\$

My problem is to Determine if number n contains the same number 3 times and if yes, print it.

I have presented number in array form. for this a, this algorithm prints 2 on console.

My algorithm looks like this:

// a = 542383272
int[] a = { 5, 4, 2, 3, 8, 3, 2, 7, 2 };

for (int i = 0; i < a.Length - 1; i++)
{
    int count = 0;
    for (int j = i + 1; j < a.Length; j++)
    {
        if (a[i] == a[j])
        {
           count++;
           if (count == 2)
              Console.WriteLine(a[i]);
        }
    }
}

My question is How can I make this algorithm faster and more efficient?

\$\endgroup\$

closed as off-topic by πάντα ῥεῖ, Stephen Rauch, Billal Begueradj, Sᴀᴍ Onᴇᴌᴀ, Ethan Bierlein Jun 4 '18 at 14:31

This question appears to be off-topic. The users who voted to close gave these specific reasons:

  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Stephen Rauch, Ethan Bierlein
  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – πάντα ῥεῖ, Billal Begueradj, Sᴀᴍ Onᴇᴌᴀ
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ count == 2 this is not 3 times :-| \$\endgroup\$ – t3chb0t Jun 2 '18 at 18:24
  • \$\begingroup\$ this, works.. the first one is already a[i]. \$\endgroup\$ – A.M Jun 2 '18 at 18:29
  • \$\begingroup\$ I am new, so can you say me what is the reason of down voting? \$\endgroup\$ – A.M Jun 2 '18 at 18:30
  • \$\begingroup\$ As I guess, some has the hobby to down vote the questions, asked by the users with low reputation score :) \$\endgroup\$ – A.M Jun 2 '18 at 18:44
  • 1
    \$\begingroup\$ @t3chb0t OP is correct. count == 2 is 3 times. Maybe if he started with count = 1 you would not have been confused. \$\endgroup\$ – paparazzo Jun 2 '18 at 19:18
2
\$\begingroup\$

You are only dealing with ten possible digit-outcomes. At the moment, your algorithm is in the order of n-squared, because for each digit in the original number you iterate through the array again (albeit slightly truncated).

You also don't address what happens if the digit occurs more than three times. I assume that this is ignored deliberately.

What you can do is run through the number once, and adjust the count of a single array. Then run through this array to identify those that have a count of 3. I am not a C# coder, so that following is pseudo code.

Split yourNumber into an array of digits (yourNumberArray) // could be a string array
Create an empty array of 10 elements (countArray) // indexes will be 0-9, which neatly matches what you want to capture - this is not a coincidence.
Traverse yourNumberArray, for each digit increment the corresponding index in countArray
After counting, traverse countArray and output those digits where the count = 3 // or whatever value you want

This will be O(n+10). Not a big deal if you are only talking a few digits, but if you are dealing with a few million digits, a big difference!

\$\endgroup\$
1
\$\begingroup\$

You can group the elements based on the number. Then get the required count.

bool HasRequiredCount(int[] elements, int count)
{
    bool result = false;
    var groupByCount = elements.ToList().GroupBy(i => i);
    foreach(var group in groupByCount)
    {
        int grpCount = group.Count();
        if (grpCount == count)
        {
            System.Diagnostics.Debug.WriteLine("YES Matched : {0} {1}", group.Key, grpCount);
            result = true;
            break;
        }
        else
        {
            System.Diagnostics.Debug.WriteLine("Not Matched: {0} {1}", group.Key, grpCount);
        }
    }

    return result;
}
\$\endgroup\$
  • \$\begingroup\$ Note that this can be simplified: foreach(int numberThatOccursAtLeastThreeTimes in elements.GroupBy(i => i).Where(g => g.Count() >= 3).Select(g => g.Key)) { Console.WriteLine(numberThatOccursAtLeastThreeTimes); There are better names than numberThatOccursAtLeastThreeTimes but I wanted to be explicit as to the meaning of the variable in the snippet. \$\endgroup\$ – Flater Jun 4 '18 at 9:29
  • \$\begingroup\$ I too agree, initially I thought of putting the condition in the query. But the idea of omitting the condition in where clause is to give generic idea. So that logic can be modify as per the requirement. \$\endgroup\$ – vishnu vardhan Jun 4 '18 at 10:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.