簡體   English   中英

如何比較沒有toCharArray方法的字謎?

[英]How to compare anagrams without toCharArray method?

/*
 * 
 * 
 */

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嗎?

我會考慮使用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());
}

那么有一些選擇。 如果您只想避免調用“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;
}

如果你通過字符串對“a”然后“b”等進行天真搜索,那么基本上你將執行冒泡排序 ,其性能將比使用quicksort的Arrays.sort()更差。

我認為toCharArray()轉換具有可忽略的一次性成本,因此嘗試微觀優化它將毫無結果。

相反 - 考慮到兩個字符串是字謎,它們的排序字母是否相等實際上並不重要,只是它們必須包含相同數量的每個字母。 也就是說,如果一個字符串包含3個A和1個B和2個N ,那么它就是BANANA的字謎。

有了這個,我們可以想象只是通過迭代第一個字符串中的每個字符並構建一個<Character, Integer>計數的Map來比較兩個字符串是否是字謎。 然后遍歷第二個字符串並對每個字符進行反向遞減計數。

掃描第二個字符串后,您只需檢查所有計數是否為零。 這種方法的一個優點是,當掃描第二個字符串時,只要字符數低於零,就可以“短路”檢查 - 這意味着第二個字符串比第一個字符串具有更多的字符,所以它們不是字謎。

假設O(1)最佳情況用於映射操作,上面概述了最佳情況O(n)算法(基本上,只通過每個字符串一次)。 在最糟糕的情況下,我認為我們正在考慮O(n^2)

將此與快速排序進行對比,快速排序具有相同的最壞情況性能但是O(n log(n))最佳情況。

當然,在實踐中,對於較短的字符串,快速排序字符數組可能會更快。 然而,隨着字符串變得更長,上述基於地圖的算法應該開始證明更有效,尤其是。 隨着短路。

您可以使用單個String.replaceAll()從字符串中刪除所有非字母字符,然后其余代碼應該是正確的。

這是因為String.replaceAll()使用正則表達式 查看用於Patternjavadocs,以便快速參考Java中的正則表達式。 特別注意Character Classes部分; 從示例中,您應該能夠構建匹配“非字母字符”的模式。 將該模式用於第一個參數,並將字符串用於String.replaceAll()第二個參數。

它在性能方面不是最有效的實現,但可能是最簡單的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM