如何比较没有toCharArray方法的字谜?

时间:2011-08-25 01:21:24

标签: java

/*
 * 
 * 
 */

import java.util.Scanner;
import java.util.Arrays;


public class Anagram
{
  public static void main(String[] args)
  {

Scanner sc = new Scanner(System.in);
String one, two;

System.out.print("Enter first sentence: ");
String s1 = sc.nextLine();
System.out.print("Enter second sentence: ");
String s2 = sc.nextLine();

sc.close();

s1 = s1.toLowerCase();
char[] chars = s1.toCharArray();
Arrays.sort(chars);
String sort1 = new String(chars);
System.out.println(sort1 + " are the letters of " + s1 + " in order");

s2 = s2.toLowerCase();
char[] chars2 = s2.toCharArray();
Arrays.sort(chars2);
String sort2 = new String(chars2);
System.out.println(sort2 + " are the letters of " + s2 + " in order");

if(sort1.equals(sort2))
  System.out.println(s1 + " is an anagram of " + s2);


  }
}

这是我的程序,使用toCharArray来比较字谜很好,但是有可能找到每个'a'到'z'并将它附加到排序列表而不是toCharArray吗?

4 个答案:

答案 0 :(得分:1)

我会考虑使用PatternMatcher类的正则表达式来查找"[a-zA-Z]"中的字符。然后,您可以遍历结果

String string = "abcd123";
Pattern pattern = Pattern.compile("[a-zA-Z]");
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
    System.out.println(matcher.group());
}

答案 1 :(得分:1)

有一些选择。如果您只想避免调用“toCharArray”,那么您可以循环遍历字符串并创建字符,但我怀疑这是您正在寻找的内容?

您还可以按如下方式执行实现(伪代码):

public void areAnagrams(String s1, String s2)
{
  int[] aNumLetters = new int[26];

  s1.toLowerCase();
  s2.toLowerCase();

  for each char c in s1
    aNumLetters[(int)c - ((int)'a')]++;

  for each char c in s2
    aNumLetters[(int)c - ((int)'a')]--;

  for each int nLetterCount in aNumLetters
    if nLetterCount != 0
      return false

  return true;
}

答案 2 :(得分:1)

如果您通过字符串对“a”然后“b”进行天真搜索,那么基本上您将执行冒泡排序,其性能将低于{{1使用quicksort。

我认为Arrays.sort()转换的成本可以忽略不计,因此尝试对其进行微观优化将会毫无结果。

相反 - 考虑到两个字符串是字谜,它们的排序字母是否相等实际上并不重要,只是它们必须包含相同数量的每个字母。也就是说,如果一个字符串包含3个toCharArray()和1个A以及2个B,那么它就是N的字谜。

有了这个,我们可以简单地通过迭代第一个字符串中的每个字符并构建BANANAMap计数来比较两个字符串是否是字谜。然后遍历第二个字符串并对每个字符进行反向递减计数。

扫描第二个字符串后,您只需检查所有计数是否为零。这种方法的一个优点是,当扫描第二个字符串时,只要字符数低于零,就可以“短路”检查 - 这意味着第二个字符串比第一个字符串具有更多的字符,所以它们不是字谜。

上面概述了一个最佳案例<Character, Integer>算法(基本上只有一个遍历每个字符串),假设O(n)的最佳情况用于地图操作。在最糟糕的情况下,我认为我们正在考虑O(1)

将此与快速排序进行对比,后者具有相同的最差情况,但O(n^2)最佳情况。

当然,在实践中,对于较短的字符串,快速排序字符数组可能会更快。然而,随着字符串变得更长,上述基于地图的算法应该开始证明更有效,尤其是。短路。

答案 3 :(得分:1)

您可以使用单个String.replaceAll()从字符串中删除所有非字母字符,然后其余代码应该是正确的。

这是因为String.replaceAll()使用正则表达式。查看javadocs for Pattern以获取Java中正则表达式的快速参考。特别注意Character Classes部分;从示例中,您应该能够构建匹配“非字母字符”的模式。将该模式用于第一个参数,将空字符串用于String.replaceAll()中的第二个参数。

在性能方面,它不是最有效的实现,但可能是最简单的代码。