2011-10-28 174 views
3

我需要编写一个函数来检查字符串是否有重复值并返回唯一字符的计数。如果计数大于3,它应该返回true。如果计数小于3,则应该是错误的。这是我一直想(请注意,我是新来的Java)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); 
    } 
} 

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

+0

我只是简单地循环,并使用字符串indexOf函数与你正在做的事情。如果你想使用正则表达式,你可以编写一个正则表达式,你只需要对该字符串使用一次。 – onit

+0

该问题要求的唯一字符的数量,但代码似乎试图计数重复....我只是读这个错误? –

+0

G_H - 谢天谢地这不是功课。我是一名初学者开发人员,尝试通过一些书籍和论坛自行学习JAVA。 – Rich

回答

1

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

既然如此,最简单的解决方案就像其他人所说的那样使用Set。事实上,你的代码几乎就在那里;刚刚摆脱numberDups柜台,并用HashSet<Character>代替它,就像这样:

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叫CharSequence的方法,如charAt()length()。变量,因为String实现CharSequence接口)


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

这是一个非常普遍的初学者的错误。无论如何,Java有着过于冗长的声誉,但在这种情况下,它尤其引人注意(并且令人惊讶)。我的意思是,什么是正则表达式,如果不是让你解决问题没有写代码大量?但并不总是那么糟糕。这里是使用一个正则表达式的单行溶液:

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

即,除去所有的重复,并且将所得的字符串的长度是一样的独特的字符的数量。尽管如此,基于集合的解决方案仍然更简单;这个只是更短。

+0

这是非常有用的很好的解释。我现在要给它一个镜头。 – Rich

+1

几点要点:如果uniqueChars的大小为3,可以提前退出for循环,而不是遍历整个String。在这种情况下,你可以创建一个初始容量为3的HashSet。 – Adamski

+0

不错的解决方案。谢谢 –

6

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

然后您需要一个数据结构来跟踪每个字符的出现次数。我建议使用HashMap来表示,因为地图关键字是您已阅读的Character,地图值是发生次数的Integer

+0

这正是我想要建议的。 –

+0

你能否提供一个你想表达的例子。这种方法听起来像我想要的。 – Rich

+0

@Rich他很清楚。你在这里不明白,所以你要求一个例子吗? –

3

算法很简单:

  1. 将字符串分割成字符
  2. 的阵列将所有这些字符设置(HashSet的)。

之后,你的设置只包含唯一的字符。

+0

虽然,不会帮助计算出现次数。只检测是否有重复的字符。 –

+0

告诉我,如果我错了,问题是“函数检查字符串的重复值,并*返回唯一字符的计数*” – mishadoff

+0

我正在调查此建议。 G_H - 这正是我期待做的。 – Rich