【问题标题】:Java - How to check for duplicate characters in a string?Java - 如何检查字符串中的重复字符?
【发布时间】:2011-12-17 09:02:49
【问题描述】:

我需要编写一个函数来检查字符串中的重复值并返回唯一字符的计数。如果计数大于 3,它应该返回 true。如果计数小于 3,则应为 false。这是我一直在尝试的(注意我是 java 新手)

private boolean isFormatValid(String password) {
    CharSequence inputStr = password;
    int length = inputStr.length();
    int numberDups = 0;

    for(int i=0; i < length; ++i) {
        Pattern pattern = Pattern.compile("(.)(?=.*?\1){1,20}");
        Matcher matcher = pattern.matcher(inputStr);
        numberDups += 1;
    }
    if (numberDups < 3) {
        return false;
    }
    return true;
}

我尝试使用正则表达式,因为有人建议它可能更容易。但是,如果我可以在没有正则表达式的情况下完成此操作,我会更开心。

这是什么意思?

private boolean isFormatValid(String password) {
    int length = inputStr.length();
    int numberChars = 0;

    for(int i=0; i < length; ++i) {
                int index = password.indexOf(i);
        CharArray[i] = charAt(i);   
    }
}

我觉得这甚至不是正确的......

【问题讨论】:

  • 我会简单地循环并按照您的方式使用字符串 indexOf 函数。如果你想使用正则表达式,你可以编写一个只需要对字符串使用一次的正则表达式。
  • 该问题要求提供唯一字符的数量,但代码似乎试图计算重复项....我只是读错了吗??
  • G_H - 幸好这不是家庭作业。我是一名初学者,尝试通过一些书籍和论坛自学 JAVA。
  • Matt - 你没有读错代码。我试图使用检查字符串长度的方法并将其与重复的数量进行比较,差异将是唯一字符的数量。但是现在它已经关闭了,这似乎过于复杂了。

标签: java regex string function duplicates


【解决方案1】:

你几乎在那里。您可以使用索引:i 来索引String,而不是使用正则表达式,并使用charAt(int) 读取特定字符。

然后您需要一个数据结构来跟踪每个字符的出现次数。我建议为此使用HashMap,其中映射键是您已阅读的Character,映射值是出现次数的Integer

【讨论】:

  • 这正是我要建议的。
  • 您能否举例说明您的意思。这种方法听起来像我想要的。
  • @Rich 他很清楚。你在这里不明白什么所以你要一个例子???
  • @Rich:如果您第一次尝试编写代码然后发布一个新问题或更新这个描述您遇到的任何问题的问题,可能会更好(为了您的理解)。 HashMap 的技巧是,如果给定字符没有映射,则添加条目: -> 1。但是,如果已经存在映射,则添加条目: -> .
  • private boolean isFormatValid(String password) { int length = inputStr.length(); int numberChars = 0; for(int i=0; i
【解决方案2】:

算法很简单:

  1. 将字符串拆分为字符数组
  2. 将所有这些字符添加到 Set (HashSet)。

之后你的集合只包含独特的字符。

【讨论】:

  • 不过,不会帮助计算出现次数。只检测是否有重复字符。
  • 如果我错了请告诉我,问题是“检查字符串中是否存在重复值并返回唯一字符数的函数”
  • 我现在正在研究这个建议。 G_H - 这正是我想要做的。
  • @mishadoff 你说得对……我太关注代码了。他确实询问了独特字符的数量。在这种情况下 +1。
【解决方案3】:

我认为您的示例代码中的变量numberDups 命名错误,这让一些人感到困惑。该变量应该表示不同字符的数量,不是吗?也就是说,如果字符串是abcabc,则数字将是3,对于字符串aaaaaaaaa,它将是1

既然如此,正如其他人所说,最简单的解决方案是使用 Set。事实上,您的代码几乎就在那里;只需去掉那个 numberDups 计数器并将其替换为 HashSet&lt;Character&gt;,如下所示:

static boolean isFormatValid(String password) {
    CharSequence inputStr = password;
    int length = inputStr.length();
    Set<Character> uniqueChars = new HashSet<Character>();

    for(int i=0; i < length; ++i) {
        uniqueChars.add(inputStr.charAt(i));
    }

    return uniqueChars.size() >= 3;
}

(但是,您不需要创建inputStr 变量。您可以在password 变量上调用charAt()length() 等CharSequence 方法,因为String 实现了CharSequence 接口。)


编辑:我还想指出,您使用 Pattern 和 Matcher 的方式,您没有使用它们。您正确地从 Pattern 中创建了 Matcher,并将其与输入字符串相关联,但它只是坐在那里。为了应用正则表达式,您必须调用其中一种方法,find()matches()(或 lookingAt(),但没有人使用过该方法)。

这是一个非常常见的初学者错误。无论如何,Java 都以过于冗长而闻名,但在这种情况下它尤其引人注目(并且令人惊讶)。我的意思是,如果不是为了让您在编写大量代码的情况下解决问题,那么正则表达式有什么用?但这并不总是那么糟糕。这是使用正则表达式的单行解决方案:

return inputStr.replaceAll("(.)(?=.*\\1)", "").length() >= 3;

即去掉所有重复,得到的字符串长度与唯一字符个数相同。但是,基于集合的解决方案仍然更简单。这个更短。

【讨论】:

  • 这对很好的解释很有帮助。我现在就试一试。
  • 几点:如果 uniqueChars 的大小为 3,您可以提前退出 for 循环,而不是遍历整个字符串。在这种情况下,您可以创建初始容量为 3 的 HashSet。
  • 不错的解决方案。谢谢
猜你喜欢
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 2016-07-06
  • 2015-01-22
  • 2016-02-12
  • 1970-01-01
  • 2012-07-14
  • 2013-07-23
相关资源
最近更新 更多