remove duplicates strings

Nov 18, 2019 at 5:35pm
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 Nov 18, 2019 at 5:37pm
Nov 18, 2019 at 5:51pm
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.#

Nov 18, 2019 at 8:28pm
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
Nov 18, 2019 at 8:32pm
this:
john
jake
zane

and output cannot be sorted
Last edited on Nov 18, 2019 at 8:32pm
Nov 18, 2019 at 8:35pm
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 Nov 18, 2019 at 8:37pm
Nov 18, 2019 at 8:59pm
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 Nov 18, 2019 at 9:04pm
Nov 18, 2019 at 9:10pm
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';
}
Nov 18, 2019 at 9:16pm
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.
Nov 18, 2019 at 9:29pm
but i want to cin these names and each name will be in a new line
Nov 18, 2019 at 9:35pm
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';
   }
}
Nov 18, 2019 at 9:39pm
the input is ended by the line (\n)
Nov 18, 2019 at 9:40pm
Then adapt the code I wrote to suit your needs.
Nov 18, 2019 at 9:43pm
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';
}
Nov 18, 2019 at 9:56pm
and how to end cin?
Nov 19, 2019 at 3:57am
> 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 ;
}
Nov 19, 2019 at 6:53am
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.