Java String Manipulation: Сравнение смежных символов в Java - PullRequest
1 голос
/ 22 марта 2011

у меня следующая проблема
Получив строку, верните «очищенную» строку, в которой соседние одинаковые символы были уменьшены до одного символа. Так что "yyzzza" дает "yza".

stringClean("yyzzza") → "yza"      
stringClean("abbbcdd") → "abcd"       
stringClean("Hello") → "Helo"

Я пробую свой код для ввода stringClean("abbbcdd") → "abcd"

Мой код приведен ниже. Я получаю частично добавленную строку после выполнения сравнения соседних символов, следовательно, теперь я получаю добавленную строкуBuilder "sb=abc", которая не является правильным выводом, я должен получить вывод как "abcd",

class cleanString{

    public static String stringClean(String str){
        int startIndex = str.indexOf(str);
        char startChar = '\u0000';
        char adjacentChar = '\u0000';
        System.out.println("startIndex-->" + startIndex);
        final StringBuilder sb = new StringBuilder();

        for(startIndex = 0; startIndex < str.length(); startIndex += 1){
            startChar = str.charAt(startIndex);
            System.out.println("startIndex ::" + startIndex);
            System.out.println("startChar ::" + startChar);

            final int adjacentPosition = startIndex + 1;
            System.out.println("adjacentPosition ::" + adjacentPosition);
            if(adjacentPosition != str.length()){
                adjacentChar = str.charAt(adjacentPosition);
                System.out.println("adjacentChar ::" + adjacentChar);
            }
            if(startChar == adjacentChar){
                System.out.println("startChar ::" + startChar);
                System.out.println("adjacentChar::" + adjacentChar);

                System.out.println("Before Substring string --->" + str);
                str = str.substring(1);
                startIndex--;
                System.out.println("After Substring string --->" + str);
                System.out.println("IndexOf check ---->"
                    + sb.toString().indexOf(startChar));
                if(sb.toString().indexOf(startChar) != -1){
                    sb.append(adjacentChar);
                    System.out.println("Appended String in if part-->"
                        + sb.toString());
                }
            } else{
                str = str.substring(1);
                startIndex--;
                sb.append(startChar);
                System.out.println("Appended String --->" + sb.toString());
            }
        }// end of for loop
        return sb.toString();
    }

    //im getting output as abc...which is partial appended string      
    public static void main(String ...args){     
        String outputCleanString=new cleanString().stringClean("abbbcdd");      
        System.out.println("Cleaned String --->"+outputCleanString);
    }      

}  

* Наблюдение: * после того, как я получаю добавленную строку «abc», а затем, когда я двигаюсь, чтобы сравнить окончательный набор символов «dd», я сталкиваюсь с проблемой в этой части.

Ответы [ 12 ]

7 голосов
/ 22 марта 2011

Если решение на основе регулярных выражений приемлемо, вы можете сделать:

str = str.replaceAll("(.)\\1+","$1");

Ideone Link

3 голосов
/ 22 марта 2011

Прежде всего, ваш код слишком сложен.Абсолютно нет необходимости

            str = str.substring(1);
            startIndex--;

внутри цикла - вы фактически удерживаете startIndex в 0 и обрезаете символы в начале строки.Вместо этого вам следует просто перебирать символы строки (и печатать str.substring(startIndex), если вы хотите увидеть, что осталось обработать).

Кроме того, здесь

            if(sb.toString().indexOf(startChar) != -1){
                sb.append(adjacentChar);
                System.out.println("Appended String in if part-->"
                    + sb.toString());
            }

вы стремитесь предотвратитьдобавление одного и того же символа снова, если он повторяется более двух раз подряд - но код на самом деле не позволяет добавлять символ в конструктор ever , если он уже есть, то есть ввод типа «aba» дастневерный вывод "ab".

И на самом деле, есть и источник вашей ошибки. Условие неверное:

            if(sb.toString().indexOf(startChar) != -1){

дает true, когдаstartChar найдено в строке, содержащейся sb!Если вы измените != на ==, вы получите свой 'd' на выходе (однако, вы также получите дополнительный 'b').

Исправленный алгоритм

ВашПодход всегда сравнивать фактический символ со следующим не удается, когда один и тот же символ повторяется более двух раз подряд.Лучше всего запомнить последний символ, добавленный в буфер, и пропустить, пока не найдете другой символ, отличный от него:

public static String stringClean(String str){
    final StringBuilder sb = new StringBuilder();
    char lastAppendedChar = '\u0000';

    for(int index = 0; index < str.length(); index += 1){
        char actualChar = str.charAt(index);

        if (actualChar != lastAppendedChar){
            sb.append(actualChar);
            lastAppendedChar = actualChar;
        }
    }// end of for loop
    return sb.toString();
}
2 голосов
/ 22 марта 2011

Проблема в вашем коде состоит в том, что вы добавляете символ не тогда, когда обнаруживается новый, а когда добавление отличается от текущего, поэтому всегда последний символ не добавляется.

1 голос
/ 15 июня 2011

Как насчет попробовать это:

public String stringClean(String string){
    char sc[] = string.toCharArray();

    for(int i =0;i<sc.length;i++){
        if(i!=sc.length-1){
            if(sc[i]!=(sc[i+1])){
                output+=sc[i];
            }
        }else {
            output+=sc[i];
        }
    }
    return  output;
    //System.out.println(output);
}
1 голос
/ 22 марта 2011
public static String stringClean(String str){
    int startIndex = str.indexOf(str);
    char startChar = '\u0000';
    char adjacentChar = '\u0000';
    boolean flag = false; // added
    System.out.println("startIndex-->" + startIndex);
    final StringBuilder sb = new StringBuilder();

    for(startIndex = 0; startIndex < str.length(); startIndex++){
        startChar = str.charAt(startIndex);
        System.out.println("startIndex ::" + startIndex);
        System.out.println("startChar ::" + startChar);

        final int adjacentPosition = startIndex + 1;
        System.out.println("adjacentPosition ::" + adjacentPosition);
        if(adjacentPosition != str.length()){
            adjacentChar = str.charAt(adjacentPosition);
            System.out.println("adjacentChar ::" + adjacentChar);
        } else {
            flag = true;
        }
        if(startChar == adjacentChar){
            System.out.println("startChar ::" + startChar);
            System.out.println("adjacentChar::" + adjacentChar);

            System.out.println("Before Substring string --->" + str);
            str = str.substring(1);
            startIndex--;
            System.out.println("After Substring string --->" + str);
            System.out.println("IndexOf check ---->"
                + sb.toString().indexOf(startChar));
            if(sb.toString().indexOf(startChar) != -1){
                sb.append(adjacentChar);
                System.out.println("Appended String in if part-->"
                    + sb.toString());
            } else if(flag) {                   /* added */
                sb.append(adjacentChar);
            }
        } else{
            str = str.substring(1);
            startIndex--;
            sb.append(startChar);
            System.out.println("Appended String --->" + sb.toString());
        }
    }// end of for loop
    return sb.toString();
}
1 голос
/ 22 марта 2011

Я бы сделал это так:

public static String stringClean(String str) {
    if (str == null || "".equals(str))
        return str;
    StringBuffer buffer = new StringBuffer();
    char[] chars = str.toCharArray();
    buffer.append(chars[0]);
    for (int i = 1; i < chars.length; i++) {
        if (chars[i] != chars[i-1])
            buffer.append(chars[i]);
    }
    return buffer.toString();
}
1 голос
/ 22 марта 2011

Если вы не ограничены в использовании коллекций из java.util, я рекомендую использовать Set.См. Пример ниже.

public static String stringClean(String input) {
    Set<Character> result = new LinkedHashSet<Character>();

    for (char c : input.toCharArray()) {
        result.add(c);
    }

    StringBuilder sb  = new StringBuilder();
    for (char c : result)
        sb.append(c);
    return sb.toString();
}
1 голос
/ 22 марта 2011
public static String stringClean(String str) {
    if (str == null || "".equals(str)) {
        return str;
    }
    char lastChar = str.charAt(0);
    StringBuilder resultBuilder = new StringBuilder();
    resultBuilder.append(lastChar);
    for (int index = 1; index < str.length(); index++) {
        char next = str.charAt(index);
        if (lastChar != next) {
            resultBuilder.append(next);
            lastChar = next;
        }
    }

    return resultBuilder.toString();
}
0 голосов
/ 04 мая 2013

Похоже, вы решаете проблемы codingbat, это хорошо,

Я тоже новичок. В этом упражнении предполагается использовать только рекурсию

Это мое решение:

public String stringClean(String str) {
  if (str.length() <= 1)
      return str;

  String adj1 = str.substring(0,1);
  String adj2 = str.substring(1,2);

  String rest = str.substring(1);

  if (adj1.equals(adj2)) {
      return stringClean(rest);
  } else
      return adj1 + stringClean(rest);
}

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

0 голосов
/ 28 марта 2011

Как насчет:

public String stringClean(String str) {
  if (str.length() < 2)return str; 

  String nextStr = str.substring(1);

  if (str.charAt(0) == str.charAt(1)) {
    return stringClean(nextStr);
  }

  else return str.substring(0,1) +  stringClean(nextStr);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...