【问题标题】:Remove adjacent duplicates from the string in Java从Java中的字符串中删除相邻的重复项
【发布时间】:2018-03-05 14:17:21
【问题描述】:

假设我有一个输入字符串为“aaabbaccd”。我需要设计一个程序,从我的输出中删除所有相邻的重复项。所以以上面的字符串为例,输出将是: 1. 删除相邻重复项后得到的第一个输出是“aad”(从我的输入中删除了 aabbcc)。 2. 在第二遍中,它会从我的字符串中删除 aa 并使我的输出为“d”。

到目前为止,我可以设计以下代码:

String input="aaabbaccd";

    String[] arr=input.split("");

    int n=arr.length;
    for(int i=0;i<n;i++) {
        if(i==arr.length-1) {
            if(arr[i-1].equals(arr[i])) {
                break;
            }
            else {
                System.out.print(arr[i]+ "");
                break;
            }
        }
        if(arr[i].equals(arr[i+1])) {
            i=i+1;
            continue;
        }
        if(!arr[i].equals(arr[i+1])) {
            System.out.print(arr[i]+ "");
        }
    }

这段代码的问题在于它给我的输出是 aad。我无法理解如何对我的代码进行第二次传递。也许递归是我需要在这段代码中实现的东西。请帮助我如何在此代码中实现递归。

【问题讨论】:

  • 你的代码是?
  • 除了缺少代码之外,我认为您甚至没有完整或清晰地描述该算法。至少向我们展示这里应该发生的事情。
  • 已添加我的代码。如果需要更多信息,请告诉我。

标签: java algorithm duplicates


【解决方案1】:

一个懒惰的替代方法是使用正则表达式,其中(.) 部分匹配任何字符并保存它,\\1 引用回该匹配项。我添加了递归以继续应用删除,直到不再修改字符串:

public String removeDuplicates(String original)
{
    String reduced = original.replaceAll("(.)\\1", "");

    if(reduced.equals(original))
        // No more duplicates, return original string
        return original;
    else
        // Duplicates were removed, continue recursion...
        return removeDuplicates(reduced);
}

通过以下方式验证行为:

@Test
public void testIt()
{
    assertThat(removeDuplicates("aaabbaccd"), is("d"));
}

【讨论】:

  • 感谢您的解决方案,您能否帮我在上面的代码中实现递归?
  • 递归是解决方案的必要部分吗?
  • 不完全是,但是,我想通过这段代码学习递归。除了递归或正则表达式之外,您还能想到任何其他解决方案吗?
  • 将等待它.. :) 如果您只能在递归中使用我的代码..
  • 为了在您的原始解决方案中递归它,您需要构建一个新的中间字符串,不仅打印字符...尝试应用我使用的相同模式,但替换 original.replaceAll用你自己的方法...
【解决方案2】:
public static void main(String[] args) {
        String input="aaabbaccd";
        removeDupe(input);


    }

    public static void removeDupe(String input) {
        String[] arr=input.split("");

        StringBuffer sb=new StringBuffer();
        int n=arr.length;
        for(int i=0;i<n;i++) {
            if(i==arr.length-1) {
                if(arr.length==1) {
                    sb.append(arr[i]);
                    break;
                }
                if(arr[i-1].equals(arr[i])) {
                    break;
                }
                else {
                    sb.append(arr[i]);
                    break;
                }
            }
            if(arr[i].equals(arr[i+1])) {
                i=i+1;
                continue;
            }
            if(!arr[i].equals(arr[i+1])) {
                sb.append(arr[i]);
            }
        }

        //System.out.println(sb);

        if(sb.toString().equals(input)) {
            System.out.println(sb);
        }
        else {
            removeDupe(sb.toString());
        }


    }

【讨论】:

  • 我建议使用 StringBuilder 而不是 StringBuffer,StringBuilder 不同步并且速度更快。
【解决方案3】:

下面的一个班轮怎么样?

(new LinkedHashSet&lt;Character&gt;("aaabbaccd".chars().mapToObj(i -&gt; (char)i).collect(Collectors.toList()))).stream().map(e -&gt; e.toString()).collect(Collectors.joining());

【讨论】:

    【解决方案4】:

    我使用 StringBuilder 类来存储字符串,并使用 StringBuilder 的replace() 方法来删​​除相邻字符。

    此语句:str.replace(i,i+2,"") 实际上会删除相邻的字符。

    核心逻辑写在一个名为remove()的静态方法中。请注意我不止一次调用remove() 方法,即 str.length()/2 次。因为要删除新字符串中的相邻对,我们每次调用remove() 后得到。

    public class RemoveDupl12{           
     public static StringBuilder remove(StringBuilder  str){    
    
       for( int i=0; i<str.length()-1; i++ )
    
        {
            if(str.charAt(i)==str.charAt(i+1))
            { 
                str.replace(i,i+2,"");
                i++;
            }
        }
        return str;
    }
    
    public static void main(String[] args) {
         StringBuilder str=new StringBuilder("daaabbad");
    
         for(int i=str.length()/2;i>0;i--)
         str=remove(str);
    
         if(str.length()==0)
             System.out.println("Final output=empty string"+str);
    
         else
             System.out.println("Final output="+str);
    }}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 2013-09-30
      • 2021-09-29
      • 2011-06-26
      相关资源
      最近更新 更多