1

I have an char array, that has some duplicate values:

A B C D E F E A

And this is my algorithm to remove the duplicate values:

char array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};
int length = 8;

    for (int i = 0; i < length; i++)
    {
        for (int j = i + 1; j < length - 1; j++)
        {
            if (array[i] == array[j])
            {
                array[j] = array[j + 1];
                length--;
            }
        }
    }

EXPECTED OUTPUT: A B C D E F
OUTPUT: A B C D E F A

I have tried to run this algorithm on papers, it seems okay when I do this in writing, however it doesn't work in my application.

5
  • I'm guessing counter is the result length. Commented Nov 4, 2014 at 13:39
  • Sorry I haven't rewritten it when I was posting here. It should be length instead of counter. Commented Nov 4, 2014 at 13:40
  • Your "duplicate removal" step reliably creates a new duplicate. Instead of a[j] == a[i] you now have a[j] == a[j+1]. Always Commented Nov 4, 2014 at 13:44
  • 2
    Learn about single stepping in a debugger, perhaps. Beats "tried to run on paper" every time. Commented Nov 4, 2014 at 13:46
  • What you posted is not an algorithm, it's code. Commented Nov 4, 2014 at 15:11

5 Answers 5

2

You should add another for loop inside the if statement check the code below:

char array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};

int length = 8;

for(int i = 0; i <= length; i++){

        for(int j = i+1; j <= length; j++){

                if(array[j] == array[i]){

                            for(int x = j+1; x <=length; x++){

                                    array[j]=array[x];

                                    }
                            length--;
                            }

                }

        }

for(int z = 0; z <= length; z++){
      cout << array[z] << " ";
      }
      cout << endl;
Sign up to request clarification or add additional context in comments.

Comments

2

You have undefined behavior.

In the first iteration of the outer loop (i = 0) and the last iteration of the inner loop (j = 7, where length = 8), array[i] == array[j] is true because both are 'A'. But then you access array[j+1], which is outside the bounds.

Then, when i = 4 and j = 6, you copy the value at 7 (which is now overwritten with garbage, but apparently happens to be 'A' in your case) to index 6, giving the wrong result you see.

You need to make the copying of the element conditional on j < (length - 1) to avoid the UB. Then you should get the right result in this instance at least.

3 Comments

Question edit reveals: There is extra space after the real data, containing NULs.
I have changed j < length to j < (length - 1), the output is A B C D E F A
@EvaldasB Well, that's wrong too. You need to check that last element, but you shouldn't copy from beyond it.
1

j < length allows [j + 1] to go beyond length

As elements are moved, length is no longer the length of valid data. counter might be, but you don't show the code for how it is initialized.

Question edited to use length-- instead of counter-- but the error is in advancing j all the way to the end in the inner loop which contains a j + 1. There is also no need to extend take i all the way to length in the outer loop since the inner loop sets jet to i + 1

1 Comment

So in first loop is set i < length - 1, so that last element wouldn't be checked and I can check the last element in other array. However the problem still persists.
1

Though I know it doesn't directly solve the question, here is the better-code alternative by which you can avoid such problems (requires C++11 for the vector initialization):

std::vector<char> in{'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};
std::vector<char> out;

std::sort (in.begin(),in.end());

std::unique_copy(in.begin(), in.end(), std::back_inserter(out));

If you do not need a copy, you can also use std::unique instead of std::unique_copy.

3 Comments

std::unique_copy removes only consecutive duplicates
THanks for the comment. So one has to do a sort in advance.
You have to sort in, not out :)
0

It only works from i=0 through 3.

When i=4, array[4] = 'E', array[j] = 'F', it passes. j++ When i=4, array[4] = 'E', array[j] = 'E', array[j] is set to array[j+1], which is 'A'.

Shifting works fine but the loop for i may be the whole length of the array instead of changed length, since it stops when i=5.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.