remove duplicates strings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
using namespace std;

void add_ch(char *str, char c)
{
    while(*str) str++;
    *str = c;
    *(str + 1) = '\0';
}

void del_first_ch(char *str)
{
    if(str == NULL)
        return;

    while(*(str + 1)){
        *str = *(str + 1);
        str ++;
    }

    *str = '\0';
}


void remove_duplicates(char *str)
{
    int tail = 1;
    int i, j;

    if(NULL == str)
        return;

    char *tmp = str;

    while(*tmp){
        tmp ++;
    }

    int len = tmp - str;
    if(len < 2)
        return;


    for(i = 1; i < len; i++){
        for(j = 0; j < tail; j ++){
            if(str[i] == str[j]){
                break;
            }
        }

        if(j == tail){
            str[tail] = str[i];
            tail ++;
        }
    }

    str[tail] = '\0';

}

int main(int argc, char* argv[])
{
    char str_list[10][20] = 
    {"abac",
    "aaaa",
    "",
    "aaaabbbbb",
    "abac",
    "tba  da"};

    for(int i = 0; i < 6; ++i){
        remove_duplicates(str_list[i]);
        cout << str_list[i]  << endl;
    }
}


I want to overwrite the code that I enter strings row by row and delete strings which are repeated. For example like this:
Input:
john
john
jake
jake
jake
zane
zane
Output:
john
jake
zane
Last edited on
Just add all your strings to a std::set<std::string>
http://www.cplusplus.com/reference/set/set/

Adding a string which is already there will do nothing.#

To be clear, do you need to remove strings that are repeated, or ones that are duplicates anywhere? Does the order of the output matter?

In other words, given this input:
john
john
jake
zane
zane
john

Do you expect this:
john
jake
zane

or this:
john
jake
zane
john

and in the first case, is it okay if the output is sorted like this:
jake
john
zane
this:
john
jake
zane

and output cannot be sorted
Last edited on
Removing neighboring duplicate strings is different than removing duplicated strings entirely.

Must you use C strings? And arrays as your container? The answer to those questions changes how to do the work.
Last edited on
One string stay (others will be removed), as I said above

I prefer to use a two-dimensional array, but I don't care
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <unordered_set>
#include <string>
#include <iostream>

int main()
{
    constexpr int names_sz = 6;
    char const* names[names_sz] = { "john", "john", "jake", "zane", "zane", "john" };
    
    std::unordered_set<std::string> unique_names(names, names + names_sz);
    
    for (auto const& name: unique_names) 
        std::cout << name << '\n';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>
#include <vector>


int main()
{
   std::vector<std::string> names { "john", "john", "jake", "zane", "zane", "john" };

   std::cout << "Original names:\n";

   for (const auto& itr : names)
   {
      std::cout << itr << ' ';
   }
   std::cout << "\n\n";

   for (auto itr { names.begin() + 1 }; itr != names.end();)
   {
      if (*(itr - 1) == *itr)
      {
         itr = names.erase(itr);
      }
      else
      {
         itr++;
      }
   }

   std::cout << "Duplicates removed:\n";

   for (const auto& itr : names)
   {
      std::cout << itr << ' ';
   }
   std::cout << '\n';
}

Original names:
john john jake zane zane john

Duplicates removed:
john jake zane john


Of course this approach won't work if there if there are "same" names with some that have capital letters and others do not. You'd have to "cleanse" the individual names to be the same.
but i want to cin these names and each name will be in a new line
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <string>
#include <vector>


int main()
{
   std::vector<std::string> names;

   while (true)
   {
      std::string input;

      std::cout << "Enter a name (QUIT to quit): ";
      std::getline(std::cin, input);

      if (input == "QUIT")
      {
         break;
      }

      names.push_back(input);
   }
   std::cout << '\n';

   std::cout << "Original names:\n";

   for (const auto& itr : names)
   {
      std::cout << itr << '\n';
   }
   std::cout << '\n';

   for (auto itr { names.begin() + 1 }; itr != names.end();)
   {
      if (*(itr - 1) == *itr)
      {
         itr = names.erase(itr);
      }
      else
      {
         itr++;
      }
   }

   std::cout << "Duplicates removed:\n";

   for (const auto& itr : names)
   {
      std::cout << itr << '\n';
   }
}
the input is ended by the line (\n)
Then adapt the code I wrote to suit your needs.
but i want to cin these names and each name will be in a new line


1
2
3
4
5
6
7
8
9
int main()
{
    std::unordered_set<std::string> unique_names;
    for (std::string line; std::getline(std::cin, line); )
        unique_names.insert(std::move(line));
    
    for (std::string const& name: unique_names) 
        std::cout << name << '\n';
}
and how to end cin?
> and how to end cin?

"the input is ended by the line (\n)". So, check for an empty string.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
#include <set>

int main()
{
    std::string unique_names ;

    std::cout << "enter names one by one; enter and empty string (or eof) to quit\n" ;

    std::set<std::string> set ;
    std::string name ;
    while( std::cout << "? " && std::getline( std::cin, name ) && !name.empty() )
        if( set.insert(name).second ) unique_names += name + '\n' ;

    std::cout << "\nunique names (in the order they were entered):\n----------------\n"
              << unique_names ;
}
or, signal end-of-file on your terminal.

On Linux, press Ctrl-D.
On Windows, enter Ctrl-Z on its own line
Topic archived. No new replies allowed.