0

I have to eliminate duplicates from a array of characters using pointers and a function. I can t get it to work correctly:

void del_copy(char *p){
int n = strlen(p);          
for (int i = 0; i < n; i++){           // Element that we compare
    for (int j = i + 1; j < n;j++){     //We compare p + i element with the rest of the elements
        if (*(p + i) == *(p + j)){        //If we find two similar, we eliminate that element by shifting
            for (int k = i; k < n; k++)
                *(p + k) = *(p + k + 1);
            }               
        }
    }
}
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • `std::unique` comes to mind. isn't it possible to just add a little "using pointers and a function"? – Cheers and hth. - Alf Dec 22 '14 at 22:36
  • 2
    You need to define the problem better. Give example input and output. Should `aaabbbaaa` become `aba`? Should it become `ab`? – user123 Dec 22 '14 at 22:37
  • 1
    Create a table of `char tbl[1 << CHAR_BIT] = {0}`. Walk the string, each character you encounter only keep it if `tbl[static_cast(ch)]++ == 0`. That's it. – WhozCraig Dec 22 '14 at 22:38
  • 3
    And btw, *pick a language*. It can *significantly* effect the answers received. – WhozCraig Dec 22 '14 at 22:40
  • possible duplicate of [Combining two strings into one string which eliminates the same letters in C](http://stackoverflow.com/questions/27334684/combining-two-strings-into-one-string-which-eliminates-the-same-letters-in-c) – 5gon12eder Dec 22 '14 at 22:42
  • @MohammadAliBaydoun It should become ab, with no duplicates. – Cezar Chirila Dec 22 '14 at 22:45
  • Removed C++ tag from title, C tag from tag list. But I agree with WhozCraig: C and C++ are two different languages. – MSalters Dec 22 '14 at 22:46

5 Answers5

3

After you do a shift the length changes. But your n doesn't take that into account.

ScottMcP-MVP
  • 10,337
  • 2
  • 15
  • 15
2

Here's a simple algorithm:

    let s be the empty set (characters encountered so far)
    let result be an empty string
    for each character c in the input string (
        if c is not in s (
            include c in s and
            append c to the end of result
            )
        )
    result is the result

For the char type on an ordinary machine with 8-bit byte, you can just use a std::bitset as set s.

Another simple algorithm is to sort the string first, if there is no requirement on preserving order. Then you can just scan it and look for duplicates.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

Here's my take at the problem. It basically uses a lookup table to check if the character has been seen before but is templated. You could use any kind of value_type.

#include <algorithm>
#include <unordered_map>

template <typename Container>
Container unique_all(Container const& c) {
  Container out;
  ::std::unordered_map<typename Container::value_type,::std::size_t> lookup;
  ::std::copy_if(c.begin(), c.end(),
      ::std::back_inserter(out),
      [&](typename Container::value_type ch) {return !lookup[ch]++;}); 
  return out;
}

You can call it like this:

unique_all(::std::string("hello dear world"))
bitmask
  • 32,434
  • 14
  • 99
  • 159
0

sample to fix

void del_copy(char *p){
    char c;
    for (int i = 0; c=*(p+i); i++){
        char *p2, *p3;
        for(p2 = p+i+1, p3 = p2; *p3; ++p3){
            if(*p3 != c)
                *p2++ = *p3;
        }
        *p2 = '\0';
    }
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

I have managed to fix my own code also. Thank you everyone for support. I had to change the if loop for a while loop and to decrement de lenght @ScottMcP-MVP.

void del_copy(char *p){
int n = strlen(p);          
for (int i = 0; i < n-1; i++){           // Element that we compare
    for (int j = i + 1; j < n;j++){     //We compare p + i element with the rest of the elements
        while(*(p + i) == *(p + j)){        //If we find two similar, we eliminate that element by shifting
            for (int k = j; k < n; k++)
                *(p + k) = *(p + k + 1);
            n--;                             //decrement n because the lenght if smaller now
        }               
    }
}
}