字符串由子串组成

时间:2015-04-19 16:25:58

标签: java algorithm

几年前,我正在接受采访并收到一个问题,我很想知道如何正确解决Java问题。给定一个字符串,如果该字符串仅由周期表元素名称中存在的字母组合组成,则返回true。

4 个答案:

答案 0 :(得分:1)

  

不一定是字谜,术语可以由多个周期元素缩写组成

您可以做的是开始收集两个字母和一个字母的缩写。

从这里你可以递归地尝试搜索两个字母(一次只有一种可能性)或一个字母匹配。这可以逐步完成,意味着最坏情况成本是O(2 ^ N)搜索时间。 (仍然非常可怕,但比蛮力更好)

e.g。说你有“酒吧”

  • 查找“ba”的两个字母的集合,这样就留下了一个不存在的字母“r”。
  • 然后回溯以寻找“b”然后“ar”两者都存在。

您可以一次搜索一个字母,然后搜索两个字母,但如果这两个字母都是解决方案,则会更慢。


如果你需要检查这个单词是否是另一组单词的字谜,你可以

public static String sortLetters(String str) {
   char[] chars = str.toLowerCase().toCharArray();
   Arrays.sort(chars);
   return new String(chars);
}

// first build a set of sorted words in lower case.
public static Set<String> buildLookup(Collection<String> words) {
   return words.stream().map(s -> sortLetters(s)).collect(toSet()));
}

// use the pre built set of words for the lookup.  O(1) operation for small words.
public static boolean isAnagram(Set<String> lookup, String word) {
    return lookup.contains(sortLetters(word));
}

答案 1 :(得分:1)

在这里看到我的答案同样的谜题:     Dynamic Programming - Word Break

这是O(N)解决方案。

答案 2 :(得分:0)

从逻辑方面来说,这相对容易,从技术上讲,元素周期表中的大多数元素名称都是2个字母。

String elements = "alcamgheo"

有些元素只是一个字母很长......所以这个问题也必须引起注意..

这里你可以通过以2个字母的间隔分割字符串来创建一个数组函数。

创建你自己的逻辑,将单个字母排序到最后,然后只读取数组,当你遇到一个数组位置包含的东西不像OC这样的元素时......那么你知道单个正在读取字母元素。所以只需将它们连接到另一个字符串中,并按每个字符的间隔读取。

答案 3 :(得分:0)

如果问题是返回给定字符串是否可以拆分为元素缩写,Java代码可能会将此委托给java.util.regex包。对于它的地狱:

import java.util.regex.Pattern;

/** is CharSequence weird enough to be split into
    chemical element abbreviations? */
class Weirdo {
    static final Pattern tabloids;
    static {
    // single character element abbreviations
        StringBuilder eap = new StringBuilder(250)
            .append("([HBCNOFPSKVYIWU]");
    //  two-character element abbreviations
        char [] abbreviations = (
            "HeLiBeNeNaMgAlSiClAr" +
            "CaScTiCrMnFeCoNiCuZnGaGeAsSeBrKr" +
            "RbSrZrNbMoTcRuRhPdAgCdInSnSbTeXe" +
            "CsBaLaCePrNdPmSmEuGdTbDyHoErTmYb" +
              "LuHfTaReOsIrPtAuHgTlPbBiPoAtRn" +
            "FrRaAcThPaNpPu").toCharArray();
        for (int i = 0 ; i < abbreviations.length ; i++) 
            eap.append('|') // tack on one alternative each
               .append(abbreviations[i++])
               .append(abbreviations[i]);
        eap.append(")*"); // allow arbitrary repetition 
        tabloids = Pattern.compile(eap.toString(),
                       Pattern.CASE_INSENSITIVE);
    }

    /** @return decomposability of <code>input</code>
     *          into element abbreviations */
    static boolean isWeird(CharSequence input) {
        return tabloids.matcher(input).matches();
    }

    public static void main(String[] args) {
        String [] toCheck =
            (null != args && 0 < args.length) ? args
            : ("Plankalkül assembler Fortran Algol Lisp " +
            "COBOL APL BASIC Simula PL/I Forth PEARL " +
            "Pascal Smalltalk C Prolog ELAN shell awk " +
            "Ada Beta Occam DACAPO Eiffel SQL Self Perl " +
            "Erlang Oberon Haskell Python Oak Lua Ruby " +
            "ECMAScript Java gBeta Swift").split(" ");
        for (String given: toCheck)
            System.out.println(given + ": " +
                               isWeird(given));
    }
}