Java String Manipulation:比较Java中的相邻字符

时间:2011-03-22 09:06:24

标签: java string

我有以下问题
给定一个字符串,返回一个“已清理”的字符串,其中相同的字符已被减少为单个字符。因此"yyzzza"会产生"yza"

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

我正在尝试输入stringClean("abbbcdd") → "abcd"

的代码

我的代码在下面。我在进行相邻的字符比较后得到了部分附加字符串,因此截至现在我得到的是附加的stringBuilder "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”im面对该部分的问题。

12 个答案:

答案 0 :(得分:7)

如果可以接受基于正则表达式的解决方案,您可以这样做:

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

Ideone Link

答案 1 :(得分:3)

首先,您的代码过于复杂。

绝对没有必要
            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());
            }

如果连续重复两次以上,你的目的是防止再次添加相同的字符 - 但是如果代码已经存在,那么代码实际上会阻止将字符添加到构建器 ,即像“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 :(得分:2)

你的代码中的问题是你不是在找到new时附加char,但是当adjetance不同然后是curent时,所以总是不会追加最后一个字符。

答案 3 :(得分:1)

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();
}

答案 4 :(得分:1)

如果您不限于使用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();
}

答案 5 :(得分:1)

我会这样做:

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();
}

答案 6 :(得分:1)

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();
}

答案 7 :(得分:1)

尝试这个怎么样:

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);
}

答案 8 :(得分:0)

function cleanString(toClean){
    return toClean.replace(/(\S)\1(\1)*/g,"$1")
}

Demo in jsFiddle

答案 9 :(得分:0)

对于您的代码和您提到的具体问题,如果相邻位置超出了您的字符串的边界,请将adjacentChar设置为null char,否则adjacentChar被视为字符串中的最后一个字符,这意味着附加不是完成。

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

else {
     adjacentChar = '/u0000';
}

修改

我认为您提到的第二个问题是在这段代码中

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

由于e和o位于Hello的缓冲区中,因此在检查Bookkeeper时会附加它们。我不认为你需要那行,所以删除它,那应该修复Hello Bookkeeper。

虽然Mohoamed的回答也会奏效。

答案 10 :(得分:0)

怎么样:

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);
}

答案 11 :(得分:0)

看起来你正在解决编码垃圾问题,这很好,

我也是初学者。这个练习应该只是使用递归

这是我的解决方案:

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);
}

希望有所帮助