【问题标题】:How to get a string consisting of all unique characters of original string preserving order?如何获取由原始字符串保留顺序的所有唯一字符组成的字符串?
【发布时间】:2015-07-31 10:32:25
【问题描述】:

给定一个字符串输入:

aaabbbcccdddeee

输出应该是:

abcde

我是如何制作这个程序的?

给定一个输入字符串,我使用冒泡排序[现在不需要高效算法]按升序对该字符串的字符进行排序,然后删除重复项。

但问题是我不能将这种方法应用于像bbkjhiaa 这样的字符串,因为它改变了我原始字符串的顺序。

我只需要使用数组和字符串的概念来编写代码。

class SingleOccurence
{
    static String singleoccurence(String p)
    {
        char current = ch[0];
        boolean found = false; //what is the use of boolean variable 
        for (int i = 0; i < ch.length; i++) 
        {
            if (current == ch[i] && !found) 
            {
                found = true;  
            }
            else if (current != ch[i])
            {
                System.out.print(current);
                current = ch[i];
                found = false;
            }
        }
        System.out.println(current);
        String s4=new String(ch);
        return s4;   
    }
    public static void main(String s[])
    {  
        String s1=new String("qwwnniitootiinn");
        String s6=SortingDemo.bubble1(s1);
        String s5=singleoccurence(s6);   
    }
}

【问题讨论】:

  • 您需要子字符串还是具有不同字符的字符串?就像@RealSkeptic 所说,你没有在这里做一个子字符串
  • @TheLostMind 是的,我需要一个不同字符的子字符串
  • @RealSkeptic 是的,我需要一个具有不同字符的子字符串
  • @javaCoderMakeSimple - 所以你需要所有字符串的唯一字符?。如果字符串是 aaabbbcccdddeee ,那么 valid 子字符串将是 aaabbbbcccd 等,而不是 abcde
  • @TheLostMind 我想那我就不需要子字符串了。我只想在字符串中打印 abcde 或 bkjhia 非重复元素

标签: java string


【解决方案1】:

确实无法对字符串进行排序,因为这可能会更改输入。

您需要做的是将整个字符串放入一个数组中,然后从头到尾遍历该数组。始终记住上次访问的值并与之进行比较。如果我们现在考虑的值和之前的一样,那么跳过它,否则显示它。

public static String deDuplicate(char[] inpt) {
    Set<Character> already_seen_chars = new HashSet<Character>();
    String result = "";

    for(int i = 0; i < inpt.length; i++) {
        if(!already_seen_chars.contains(inpt[i])) { // Is the character already contained in the set?
            result += Character.toString(inpt[i]);
            already_seen_chars.add(inpt[i]);
        }
    }

    return result;
}

public static void main(String[] args) {
    String test = "ttttteeeeesssstttt";
    System.out.println(deDuplicate(test.toCharArray()));
}

输入:qwwnniitootiinn,输出:qwnito

请注意,性能也和以前一样好,O(n) 而不是 O(n^2)(其中 n 是字符串的长度)。

编辑:如果不允许使用 Set 数据结构,则可以将 mySet.contains(...) 替换为 for 循环,该循环遍历字符串并检查字符。

这给出了:

public static String deDuplicate(String input) {
    char[] inpt = input.toCharArray();
    String result = "";

    for(int i = 0; i < inpt.length; i++) {
        if(!contains(inpt, inpt[i], i)) { // Is the character already contained in the set?
            result += Character.toString(inpt[i]);
        }
    }

    return result;
}

contains 函数是:

public static boolean contains(char[] inpt, char c, int maxIndex) {
    for(int i = 0; (i < inpt.length) && (i < maxIndex); i++) {
        if(inpt[i] == c)
            return true;
    }

    return false;
}

请注意,这会影响性能! deDuplicate 中的 for 循环现在调用 contains,其中还包含一个 for 循环。因此导致 O(n^2) 性能。

【讨论】:

  • 为什么您的代码没有为输入 tttjeessttj 获得正确的输出?应该是ttjes。
  • 我给你的代码是消除重复字符(如问题标题中所述)。所以 tttjeessttj 消除重复字符后,结果是 tjestj 而不是 ttjes ,这里仍然是重​​复的(tt)并且字符的顺序改变了......?但是问题表明您想保留原始字符串的序列。如果这不是您想要的,请更清楚地了解所需的行为。
  • 我们必须删除字符串中的重复性。因此,如果字符已经出现,则无需打印字符,换句话说,打印字符串中的唯一字符。对造成的任何不便,我们深表歉意。
  • @javaCoderMakeSimple 我编辑了它,现在它不再与前一个字符比较,而是与所有访问的字符进行比较,以过滤掉重复的字符。请注意,tjestj 现在的结果是 tjes,但不是 ttjes,因为 t 在后者中出现了 2 次。
  • 您使用的是HashSet,这是个好主意,但 OP 说要求是只使用字符串和数组。
【解决方案2】:

这对你有用:

public static void main(String[] args) {    
    String s = "aaabbbcccdddeee";
    System.out.println(s.replaceAll("(.)(?=.*\\1)",""));
}

O/P:

abcde

对于输入:bbkjhiaa O/P : bkjhia

【讨论】:

  • 他的作业只需要使用字符串和数组,我认为使用正则表达式不在那个域中。
  • @RealSkeptic - 好吧,我想在这里尽我的一份力:)
  • 是的,因为我正在练习关于字符串和数组的问题。如果该方法只能使用这些概念会很有帮助。另外,对于没有人指向的测试用例,例如我有输入aabbccddaabb 我想输出为 abcd。
  • @javaCoderMakeSimple - 我的代码处理你的情况。另外,如果你只需要字符串概念,那么你可能需要一个带有subString()contains()indexOf() 的循环 :) (不要添加 - 和很多耐心 :P)
  • @LostMind 是的,我会尽力而为。感谢您的提示:) :P
【解决方案3】:

删除重复数据的最简单方法是使用Set,因为sets only allow each object in them to appear once

例子:

String onlyUniqueCharacters(String s) {
    final StringBuilder sb = new StringBuilder();
    final Set<Character> uniqueChars = new HashSet<>();
    for (int i = 0; i < s.length(); i++) {
        final char c = s.charAt(i);
        if (uniqueChars.add(c) sb.append(c);
    }
    return sb.toString();
 }

【讨论】:

  • 设置不保留顺序
  • 集合不保持顺序,但这里的代码会 - 它按顺序查看每个字符,并将其复制到保持顺序的StringBuilder,但前提是该字符尚未出现之前,根据集合
猜你喜欢
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 2013-04-10
  • 1970-01-01
  • 2011-02-03
相关资源
最近更新 更多