Удаление дубликатов из строки в Java

Я пытаюсь выполнить итерацию по строке, чтобы удалить дубликаты символов.

Например, строка aabbccdef должна стать abcdef и строка abcdabcd должна стать abcd

Вот что я до сих пор:

public class test {

    public static void main(String[] args) {

        String input = new String("abbc");
        String output = new String();

        for (int i = 0; i < input.length(); i++) {
            for (int j = 0; j < output.length(); j++) {
                if (input.charAt(i) != output.charAt(j)) {
                    output = output + input.charAt(i);
                }
            }
        }

        System.out.println(output);

    }

}

Каков наилучший способ сделать это?

Ответ 1

Преобразуйте строку в массив char и сохраните ее в LinkedHashSet. Это сохранит ваш заказ и удалит дубликаты. Что-то вроде:

String string = "aabbccdefatafaz";

char[] chars = string.toCharArray();
Set<Character> charSet = new LinkedHashSet<Character>();
for (char c : chars) {
    charSet.add(c);
}

StringBuilder sb = new StringBuilder();
for (Character character : charSet) {
    sb.append(character);
}
System.out.println(sb.toString());

Ответ 2

Я бы воспользовался помощью LinkedHashSet. Удаляет дубликаты (поскольку мы используем Set, поддерживаем заказ, когда используем связанный список impl). Это своего рода грязное решение. может быть даже лучший способ.

String s="aabbccdef";
Set<Character> set=new LinkedHashSet<Character>();
for(char c:s.toCharArray())
{
    set.add(Character.valueOf(c));
}

Ответ 3

Попробуйте это простое решение:

public String removeDuplicates(String input){
    String result = "";
    for (int i = 0; i < input.length(); i++) {
        if(!result.contains(String.valueOf(input.charAt(i)))) {
            result += String.valueOf(input.charAt(i));
        }
    }
    return result;
}

Ответ 4

Использование Stream делает это легко.

import java.util.Arrays;
import java.util.stream.Collectors;

public class MyClass {

    public static String removeDuplicates(String myString) {
        return Arrays.asList(myString.split(""))
                     .stream()
                     .distinct()
                     .collect(Collectors.joining());
    }
}

Вот еще немного документации о Stream и все, что вы можете с ней сделать: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

Часть "описание" очень поучительна о преимуществах Streams.

Ответ 5

Создайте StringWriter. Запустите исходную строку, используя charAt (i) в цикле for. Ведите переменную типа char, сохраняя последнее значение charAt. Если вы повторяете и значение charAt равно тому, что хранится в этой переменной, не добавляйте к StringWriter. Наконец, используйте метод StringWriter.toString() и получите строку и сделайте то, что вам нужно.

Ответ 6

public class RemoveRepeated4rmString {

    public static void main(String[] args) {
        String s = "harikrishna";
        String s2 = "";
        for (int i = 0; i < s.length(); i++) {
            Boolean found = false;
            for (int j = 0; j < s2.length(); j++) {
                if (s.charAt(i) == s2.charAt(j)) {
                    found = true;
                    break; //don't need to iterate further
                }
            }
            if (found == false) {
                s2 = s2.concat(String.valueOf(s.charAt(i)));
            }
        }
        System.out.println(s2);
    }
}

Ответ 7

    String input = "AAAB";

    String output = "";
    for (int index = 0; index < input.length(); index++) {
        if (input.charAt(index % input.length()) != input
                .charAt((index + 1) % input.length())) {

            output += input.charAt(index);

        }
    }
    System.out.println(output);

но вы не можете его использовать, если вход имеет те же самые элементы, или если его пустой!

Ответ 8

Код для удаления повторяющихся символов в строке без использования дополнительного буфера. ПРИМЕЧАНИЕ. Одна или две дополнительные переменные являются точными. Дополнительный массив отсутствует:

import java.util.*;
public class Main{
    public static char[] removeDupes(char[] arr){
        if (arr == null || arr.length < 2)
            return arr;
        int len = arr.length;
        int tail = 1;
        for(int x = 1; x < len; x++){
            int y;
            for(y = 0; y < tail; y++){
                if (arr[x] == arr[y]) break;
            }
            if (y == tail){
                arr[tail] = arr[x];
                tail++;
            }
        }
        return Arrays.copyOfRange(arr, 0, tail);
    }

    public static char[] bigArr(int len){
        char[] arr = new char[len];
        Random r = new Random();
        String alphabet = "[email protected]#$%^&*()-=_+[]{}|;:',.<>/?`~";

        for(int x = 0; x < len; x++){
            arr[x] = alphabet.charAt(r.nextInt(alphabet.length()));
        }

        return arr;
    }
    public static void main(String args[]){

        String result = new String(removeDupes(new char[]{'a', 'b', 'c', 'd', 'a'}));
        assert "abcd".equals(result) : "abcda should return abcd but it returns: " + result;

        result = new String(removeDupes(new char[]{'a', 'a', 'a', 'a'}));
        assert "a".equals(result) : "aaaa should return a but it returns: " + result;

        result = new String(removeDupes(new char[]{'a', 'b', 'c', 'a'}));
        assert "abc".equals(result) : "abca should return abc but it returns: " + result;

        result = new String(removeDupes(new char[]{'a', 'a', 'b', 'b'}));
        assert "ab".equals(result) : "aabb should return ab but it returns: " + result;

        result = new String(removeDupes(new char[]{'a'}));
        assert "a".equals(result) : "a should return a but it returns: " + result;

        result = new String(removeDupes(new char[]{'a', 'b', 'b', 'a'}));
        assert "ab".equals(result) : "abba should return ab but it returns: " + result;


        char[] arr = bigArr(5000000);
        long startTime = System.nanoTime();
        System.out.println("2: " + new String(removeDupes(arr)));
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        System.out.println("Program took: " + duration + " nanoseconds");
        System.out.println("Program took: " + duration/1000000000 + " seconds");

    }
}

Как читать и говорить о вышеуказанном коде:

  • Метод, называемый removeDupes, принимает массив примитивных char, называемых arr.
  • arr возвращается как массив примитивных символов "по значению". Принятый arr - это мусор, собранный в конце метода Main member removeDupes.
  • Сложность выполнения этого алгоритма - O (n) или, более конкретно, O (n + (малая константа)), константа - это уникальные символы во всем массиве примитивных символов.
  • CopyOfRange не увеличивает значительную сложность выполнения, поскольку только копирует небольшое постоянное количество элементов. Массив char, называемый arr, не проходит полностью.
  • Если вы передаете null в removeDupes, метод возвращает null.
  • Если вы передаете пустой массив примитивных символов или массив, содержащий одно значение, возвращается немодифицированный массив.
  • Метод removeDupes происходит настолько же быстро, насколько это возможно физически, полностью используя кеш L1 и L2, поэтому Перенаправления веток сохраняются до минимума.
  • Укомплектованный компьютером стандартный выпуск 2015 года должен иметь возможность завершить этот метод с помощью примитивного массива char, содержащего 500 миллионов символов в пределах от 15 до 25 секунд.

Объясните, как работает этот код:

Первая часть переданного массива используется как репозиторий для уникальных символов, которые в конечном итоге возвращены. В начале функции ответ: "символы от 0 до 1" от 0 до хвоста.

Мы определяем переменную y вне цикла, потому что мы хотим найти первое место, где индекс массива, который мы рассматриваем, был дублирован в нашем репозитории. Когда найден дубликат, он вырывается и завершается, хвост y == возвращает false, а репозиторий не предоставляется.

когда индекс x, который мы просматриваем, не представлен в нашем репозитории, мы вытягиваем его и добавляем в конец нашего репозитория по хвосту индекса и хвосту инкремента.

В конце мы возвращаем массив между точками 0 и хвостом, который должен быть меньше или равен длине исходному массиву.

Обсуждение упражнений для интервью с корером:

Будет ли программа вести себя по-другому, если вы измените y ++ на ++ y? Почему или почему нет.

Копирует ли массив в конце другой "N" проход через весь массив, создавая сложность выполнения O (n * n) вместо O (n)? Почему или почему нет.

Можно ли заменить double равным сравнению примитивных символов с .equals? Почему или почему нет?

Можно ли изменить этот метод, чтобы выполнить замены "по ссылке" вместо того, что теперь, "по значению"? Почему или почему нет?

Можете ли вы повысить эффективность этого алгоритма, отсортировав репозиторий уникальных значений в начале 'arr'? При каких обстоятельствах это будет более эффективно?

Ответ 9

Вот улучшение ответа от Dave.

Он использует HashSet вместо немного более дорогостоящего LinkedHashSet и повторно использует буфер chars для результата, устраняя необходимость в StringBuilder.

String string = "aabbccdefatafaz";

char[] chars = string.toCharArray();
Set<Character> present = new HashSet<>();
int len = 0;
for (char c : chars)
    if (present.add(c))
        chars[len++] = c;

System.out.println(new String(chars, 0, len));   // abcdeftz

Ответ 10

Мне кажется, что каждый пытается слишком усердно выполнить эту задачу. Все, о чем нас беспокоит, заключается в том, что он копирует 1 копию каждой буквы, если она повторяется. Тогда, поскольку нас беспокоит только то, повторяют ли эти символы один за другим, вложенные циклы становятся произвольными, поскольку вы просто можете просто сравнить позицию n с положением n + 1. Тогда, поскольку это только копирует вещи вниз, когда они разные, последний символ, вы можете либо добавить белое пространство в конец исходной строки, либо просто скопировать его, чтобы скопировать последний символ строки в результат.

String removeDuplicate (String s) {

    String result = "";

    for (int i = 0; i < s.length(); i++){
        if (i + 1 < s.length() && s.charAt(i) != s.charAt(i+1)){
            result = result + s.charAt(i);
        }
        if (i + 1 == s.length()){
            result = result + s.charAt(i);
        }
    }

    return result;

}

Ответ 11

Я думаю, что работать таким образом было бы проще ,, Просто передайте строку этой функции, и работа сделана :).

private static void removeduplicate(String name)
{   char[] arr = name.toCharArray();
    StringBuffer modified =new StringBuffer();
    for(char a:arr)
    {
        if(!modified.contains(Character.toString(a)))
        {
            modified=modified.append(Character.toString(a)) ;
        }
    }
    System.out.println(modified);
}

Ответ 12

Вы не можете. Вы можете создать новую строку, у которой дубликаты удалены. Почему вы не используете StringBuilder (или StringBuffer, предположительно)?

Вы можете запустить строку и сохранить уникальные символы в массиве char [], отслеживая количество уникальных символов, которые вы видели. Затем вы можете создать новую строку с помощью конструктора String(char[], int, int).

Кроме того, проблема немного неоднозначна: "дубликаты" означают смежные повторения? (Другими словами, что должно произойти с abcab?)

Ответ 13

Хорошо, ребята, я нашел лучший способ сделать это

public static void alpha(char[] finalname)
{
    if (finalname == null)
    {
        return;
    }

    if (finalname.length <2)
    {
        return;
    }

    char empty = '\000';
    for (int i=0; i<finalname.length-1; i++)
    {
        if (finalname[i] == finalname[i+1])
        {
            finalname[i] = empty;
        }
    }

    String alphaname = String.valueOf(finalname);
    alphaname = alphaname.replace("\000", "");
    System.out.println(alphaname);


}

Ответ 14

Oldschool way (как мы писали такие задачи в Apple] [Basic, адаптированный к Java):

int i,j;
StringBuffer str=new StringBuffer();
Scanner in = new Scanner(System.in);
System.out.print("Enter string: ");
str.append(in.nextLine());

for (i=0;i<str.length()-1;i++){
    for (j=i+1;j<str.length();j++){
        if (str.charAt(i)==str.charAt(j))
            str.deleteCharAt(j);
    }
}
System.out.println("Removed non-unique symbols: " + str);

Ответ 15

Вот еще одна логика, которую я хотел бы поделиться. Вы начинаете сравнивать с середины длины строки и идите назад.

Тест с: input = "azxxzy"; output = "ay";

String removeMidway(String input){
        cnt = cnt+1;
        StringBuilder str = new StringBuilder(input);
        int midlen = str.length()/2;
        for(int i=midlen-1;i>0;i--){

            for(int j=midlen;j<str.length()-1;j++){     
                if(str.charAt(i)==str.charAt(j)){
                    str.delete(i, j+1);
                    midlen = str.length()/2;
                    System.out.println("i="+i+",j="+j+ ",len="+ str.length() + ",midlen=" + midlen+ ", after deleted = " + str);
                }
            }
        }       
        return str.toString();
    }

Ответ 16

Это еще один подход

void remove_duplicate (char* str, int len) {
    unsigned int index = 0;
    int c = 0;
    int i = 0;
    while (c < len) {
        /* this is just example more check can be added for
           capital letter, space and special chars */

        int pos = str[c] - 'a';
        if ((index & (1<<pos)) == 0) {
            str[i++] = str[c];
            index |= (1<<pos);
        }
        c++;
    }
    str[i] = 0;
}

Ответ 17

Другим возможным решением, в случае, если строка является строкой ASCII, является поддержка массива из 256 булевых элементов для обозначения символа ASCII в строке. Если персонаж появился впервые, мы сохраняем его и добавляем к результату. В противном случае просто пропустите его.

public String removeDuplicates(String input) {
    boolean[] chars = new boolean[256];
    StringBuilder resultStringBuilder = new StringBuilder();
    for (Character c : input.toCharArray()) {
        if (!chars[c]) {
            resultStringBuilder.append(c);
            chars[c] = true;
        }
    }
    return resultStringBuilder.toString();
}

Этот подход также будет работать с строкой Unicode. Вам просто нужно увеличить размер chars.

Ответ 18

Решение с использованием JDK7:

public static String removeDuplicateChars(final String str){

    if (str == null || str.isEmpty()){
        return str;
    }

    final char[] chArray = str.toCharArray();
    final Set<Character> set = new LinkedHashSet<>();
    for (char c : chArray) {
        set.add(c);
    }

    final StringBuilder sb = new StringBuilder();
    for (Character character : set) {
        sb.append(character);
    }
    return sb.toString();
}

Ответ 19

 public static void main(String a[]){
      String name="Madan";
      System.out.println(name);
      StringBuilder sb=new StringBuilder(name);
      for(int i=0;i<name.length();i++){
          for(int j=i+1;j<name.length();j++){
             if(name.charAt(i)==name.charAt(j)){
              sb.deleteCharAt(j);

             }
          }
      }
     System.out.println("After deletion :"+sb+"");

    }

Ответ 20

    String str = "[email protected]";
    char[] c = str.toCharArray();
    String op = "";

    for(int i=0; i<=c.length-1; i++){
        if(!op.contains(c[i] + ""))
        op = op + c[i];
    }
    System.out.println(op);

Ответ 21

public static String removeDuplicateChar(String str){
         char charArray[] = str.toCharArray();
         StringBuilder stringBuilder= new StringBuilder();
         for(int i=0;i<charArray.length;i++){
             int index = stringBuilder.toString().indexOf(charArray[i]);
             if(index <= -1){
                 stringBuilder.append(charArray[i]);
             }
         }
         return stringBuilder.toString();
    }

Ответ 22

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class RemoveDuplicacy
{
        public static void main(String args[])throws IOException
        {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.print("Enter any word : ");
            String s = br.readLine();
            int l = s.length();
            char ch;
            String ans=" ";

            for(int i=0; i<l; i++)
            {
                ch = s.charAt(i);
                if(ch!=' ')
                    ans = ans + ch;
                s = s.replace(ch,' '); //Replacing all occurrence of the current character by a space
            }

           System.out.println("Word after removing duplicate characters : " + ans);
        }

}

Ответ 23

import java.util.Scanner;

public class dublicate {
    public static void main(String... a) {
        System.out.print("Enter the String");
        Scanner Sc = new Scanner(System.in);
        String st=Sc.nextLine();
        StringBuilder sb=new StringBuilder();
        boolean [] bc=new boolean[256];
        for(int i=0;i<st.length();i++)
        {
            int index=st.charAt(i);
            if(bc[index]==false)
            {
                sb.append(st.charAt(i));
                bc[index]=true;
            }

        }
        System.out.print(sb.toString());
    }
}

Ответ 24

public static void main(String[] args) {

    int i,j;
    StringBuffer str=new StringBuffer();
    Scanner in = new Scanner(System.in);
    System.out.print("Enter string: ");

    str.append(in.nextLine());

    for (i=0;i<str.length()-1;i++)
    {
        for (j=1;j<str.length();j++)
        {
            if (str.charAt(i)==str.charAt(j))
                str.deleteCharAt(j);
        }
    }
    System.out.println("Removed String: " + str);
}

Ответ 25

Это улучшает решение, предлагаемое @Dave. Здесь я реализую только один цикл.

Пусть повторно использует метод set.add(T item) и добавляет его одновременно в StringBuffer, если add успешно

Это просто O (n). Нет необходимости снова создавать цикл.

String string = "aabbccdefatafaz";

char[] chars = string.toCharArray();
StringBuilder sb = new StringBuilder();
Set<Character> charSet = new LinkedHashSet<Character>();
for (char c : chars) {
    if(charSet.add(c) ){
        sb.append(c);
    }

}
System.out.println(sb.toString()); // abcdeftz

Ответ 26

Простым решением является итерация по данной строке и включение каждого уникального символа в другую строку (в данном случае переменную result), если эта строка не содержит этого конкретного символа. Наконец верните result в качестве вывода.

Ниже приведен рабочий и проверенный фрагмент кода для удаления повторяющихся символов из заданной строки с временной сложностью O (n).

private static String removeDuplicate(String s) {
      String result="";
      for (int i=0 ;i<s.length();i++) {
          char ch = s.charAt(i);
          if (!result.contains(""+ch)) {
              result+=""+ch;
          }
      }
      return result;
  }

Если вход madam, то вывод будет безумным.
Если вход анаграмма, то вывод будет angrm

Надеюсь, что это поможет. Благодаря

Ответ 27

Для простоты кода я взял хардкорный ввод, можно взять ввод с помощью класса Scanner также

    public class KillDuplicateCharInString {
    public static void main(String args[]) {
        String str= "aaaabccdde ";
        char arr[]= str.toCharArray();
        int n = arr.length;
        String finalStr="";
        for(int i=0;i<n;i++) {
            if(i==n-1){
                finalStr+=arr[i];
                break;
            }
            if(arr[i]==arr[i+1]) {
                continue;
            }
            else {
                finalStr+=arr[i];
            }
        }
        System.out.println(finalStr);



    }
}

Ответ 28

 public static void main (String[] args)
 {
    Scanner sc = new Scanner(System.in);
    String s = sc.next();
    String str = "";
    char c;
    for(int i = 0; i < s.length(); i++)
    {
        c = s.charAt(i);
        str = str + c;
        s = s.replace(c, ' ');
        if(i == s.length() - 1)
        {
           System.out.println(str.replaceAll("\\s", ""));   
        }
    }
}

Ответ 29

package com.st.removeduplicate;
 public class RemoveDuplicate {
   public static void main(String[] args) {
    String str1="shushil",str2="";      
    for(int i=0; i<=str1.length()-1;i++) {
        int count=0;
        for(int j=0;j<=i;j++) {
            if(str1.charAt(i)==str1.charAt(j)) 
                count++;
            if(count >1)
                break;
        }
        if(count==1) 
            str2=str2+str1.charAt(i);
    }
    System.out.println(str2);

}

}

Ответ 30

Надеюсь, это поможет.

public void RemoveDuplicates() {
    String s = "Hello World!";
    int l = s.length();
    char ch;
    String result = "";
    for (int i = 0; i < l; i++) {
        ch = s.charAt(i);
        if (ch != ' ') {
            result = result + ch;
        }
        // Replacing space in all occurrence of the current character
        s = s.replace(ch, ' ');
    }
    System.out.println("After removing duplicate characters : " + result);
}