emideveloper
emideveloper

Reputation: 1

how to replace duplicates in row 2d array

I have an 2d array with chars 6x6 and looks something like this and Im trying to create an method witch needs to replace duplicates in row with '@' character

 a b a a
 a a b c
 a a a b
 a a a a

and after replacing with method should look like this

a b @ @
a @ b c
a @ @ b
a @ @ @

I have tried this method but no results "I need to make this work without libraries"

 public  void RemoveDuplicates(char[,] array)
    {
        char symbol = '@';

        for (int i = 0; i < array.GetLength(0); i++)
        {
            for (int j = 0; j < array.GetLength(1); j++)
            {
                int temp = array[i, j];
                int next = ++temp;

                if(temp == next)
                {
                    next = symbol;
                }

            }
        }
    }

Upvotes: 0

Views: 212

Answers (3)

Sayroyten
Sayroyten

Reputation: 60

Probably not the fastest solution but pretty simple to understand

Considering this input

var data = new char[,]
        {
            { 'a', 'b', 'a', 'a' },
            { 'a', 'a', 'b', 'c' },
            { 'a', 'a', 'a', 'b' },
            { 'a', 'a', 'a', 'a' },
        };

With this code it will take each row, one by one, then replace duplicated values

        //for each row
        for (int i = 0; i < data.GetLength(0); i++)
        {
            //for each cell
            for (int j = 0; j < data.GetLength(1); j++)
            {
                //for each cell compare all next cells
                for (int k = data.GetLength(1) - 1; k > j; k--)
                {
                    if (data[i, j] == data[i, k])
                    {
                        data[i, k] = '@';
                    }
                }
            }
        }

Result:

a b @ @
a @ b c
a @ @ b
a @ @ @

PS: You can improve a bit the code by iterating "data.GetLength(1) -1" as the last cell cant have a duplicate.

And skip the loop if the value of the cell is '@', in the current code you will replace some '@' by another '@' :D

Upvotes: 1

IKomarovLeonid
IKomarovLeonid

Reputation: 390

You can use Hashset (or list also) collection (docs: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/collections) to store your duplicates as follows:

    var hash = new HashSet<char>(); 

    for (int i = 0; i < array.GetLength(0); i++)
    {
        for (int j = 0; j < array.GetLength(1); j++)
        {
             if(!hash.Add(array[i,j])) array[i,j] = '@';
        }
        hash.Clear();
    }

Or list as follows:

    var list = new List<char>();
    
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    if(!list.Contains(array[i,j])) list.Add(array[i,j]);
                    else array[i,j] = '@';
                }
                list.Clear();
            }

Upvotes: 3

JonasH
JonasH

Reputation: 36596

The goal should be to keep track of all previously seen characters. So you need some kind of 'set' data structure for this. The easy way would be to use an HashSet. This has an add method that adds the value to the set, and return false if the value was already in the set.

var seenCharacters = new HashSet<char>();
for (int j = 0; j < array.GetLength(1); j++)
{
    if(!seenCharacters.Add(array[i, j])){
         array[i, j] = symbol;
    }
}

HashSet is part of the framework, so would not normally be considered a "library".

If that is now allowed you could provide similar functionality with an plain array.

var seenCharacters = new bool[(int)char.MaxValue];
for (int j = 0; j < array.GetLength(1); j++)
{
    var c = (int)array[i, j];
    if(seenCharacters[c]){
         array[i, j] = symbol;
    }
    seenCharacters[c] = true;
}

But I would probably not recommend such a solution since it uses much more memory compared to the hashSet.

Upvotes: 0

Related Questions