[ポイント]第一区分に第2のストリング、実現文字列分割()関数法を用いて、二つの文字列のコードが与えられます。要求は、SUBSTRING()およびネイティブスプリット()メソッドを使用していません

友人数日前には、その後、私のようなコードの問題を投げた、と私は私が最初に考えたが、この質問はleetcodeではないことであった任意のアイデアは、この株式は、私がそれを強制的にロードされ誇示したくありませんでした場合は私に尋ねましたleetcodeプログラマではない深い接点として、恥ずかしい:どのようにできた短時間彼のトレーニングと準備、そして彼の顔に深刻な打撃の両方の正確かつ効率的なコードはまだ、(PSそれは恥ずかしいです)。ハッハッハ、冗談、仕事に取り掛かります。

私が思っていたので、カーソルが不可能であると、文字列のこのセグメンテーションといえば、私は最初、ポインタを移動する、特定の端からもう一方の端に、実際には、カーソルと呼ばれるカーソルの概念にさらされる学生を、と思いましたまだこの問題を解決するための戦略として。上記のアイデア、迅速な櫛に基づき、介護には、以下のキーポイントを達成するために行う必要があります。

  1. 順次、第1ストリング添字0より後ろからカーソルとしての第2のストリング。
  2. 何の使用SUBSTRING()メソッドがなかったので、私は、配列を使用することであると考えることができるように左と右のは、その後、彼らは論理的な全体として文字列を対照的な2については避けるだろう、二つの可能性が高い複数の文字であることをしていると比較します。
  3. 整合部分を区別部分と一致しない方法ああ、パッケージングを使用することができる特別な値が効果を区別するために、ヌル値に達すると、それは使用することができます。
  4. カーソル横断の終了後に、ヌル値またはヌル値は、結果セットとプロセス制御の完了を組み立てるために、後続の決意論理として、全体の分割境界として連続的であろう。

(:などの特殊文字は、nullポインタ、現在検討されていないコードがバグいくつかの点をも)いくつかの単語の男は、直接コードに、と述べました。

public class SplitDemo {

    public List<String> split(String str, String reg) {
        List<String> result = new ArrayList<>();
        Character[] strArr = toCharacterArray(str);
        Character[] regArr = toCharacterArray(reg);
        //游标逻辑
        for (int i = 0; i < strArr.length; i++) {
            //标识多字符是否完全匹配
            boolean flag = false;
            for (int j = 0; j < regArr.length; j++) {
                flag = regArr[j].equals(strArr[i + j]);
                if (!flag) {
                    break;
                }
            }
            if (!flag) {
                continue;
            }
            //特殊null值赋值
            for (int j = 0; j < regArr.length; j++) {
                strArr[i + j] = null;
            }
        }
        //结果集封装
        String item = "";
        for (Character character : strArr) {
            if (null != character) {
                item = item + character;
            } else {
                if (!"".equals(item)) {
                    result.add(item);
                    item = "";
                }
            }
        }
        if (!"".equals(item)) {
            result.add(item);
        }
        return result;
    }
    /**
    将字符串转为字符包装类数组
    */
    private Character[] toCharacterArray(String str) {
        Character[] result = new Character[str.length()];
        for (int i = 0; i < result.length; i++) {
            result[i] = str.charAt(i);
        }
        return result;
    }
}
复制代码

試験方法

    public static void main(String[] args) {
        List<String> result = new SplitDemo().split("asasdecdsdxa", "sd");
        for (String str : result) {
            System.out.println(str);
        }
    }
复制代码

出力

最初は完了したが、友人は交換を掲示した後、少し退屈を感じ、別のアプローチがあります。友人の直接コードのスクリーンショット。

このコードは、いくつかの重要なポイントがあります。

  1. indexOf(文字列str、INT fromIndexの場合)、第2の文字列の最初の完全なヘッダに最初に一致した文字列を返し、-1に一致しない場合。
  2. 最初の文字列の位置を制御するために、初期決意と一致、すなわちのindexOfパラメータformIndexに(文字列str、INTたfromIndex)、順次効果を達成するために繰り返して取ら。

全体の論理は非常に明確であり、コードの量が少なく、より効率的な予備的な判断、ここで私は助けることはできませんが、好奇心いっぱいのStringクラスのindexOf(文字列str、int型formIndex)メソッドに、私たちはどのようなJDKのソースコード(バージョンJDK8)を追求してみましょう。

    /**
     * Returns the index within this string of the first occurrence of the
     * specified substring, starting at the specified index.
     *
     * <p>The returned index is the smallest value <i>k</i> for which:
     * <blockquote><pre>
     * <i>k</i> &gt;= fromIndex {@code &&} this.startsWith(str, <i>k</i>)
     * </pre></blockquote>
     * If no such value of <i>k</i> exists, then {@code -1} is returned.
     *
     * @param   str         the substring to search for.
     * @param   fromIndex   the index from which to start the search.
     * @return  the index of the first occurrence of the specified substring,
     *          starting at the specified index,
     *          or {@code -1} if there is no such occurrence.
     */
    public int indexOf(String str, int fromIndex) {
        return indexOf(value, 0, value.length,
                str.value, 0, str.value.length, fromIndex);
    }
    
    /**
     * Code shared by String and StringBuffer to do searches. The
     * source is the character array being searched, and the target
     * is the string being searched for.
     *
     * @param   source       the characters being searched.
     * @param   sourceOffset offset of the source string.
     * @param   sourceCount  count of the source string.
     * @param   target       the characters being searched for.
     * @param   targetOffset offset of the target string.
     * @param   targetCount  count of the target string.
     * @param   fromIndex    the index to begin searching from.
     */
    static int indexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        if (fromIndex >= sourceCount) {
            return (targetCount == 0 ? sourceCount : -1);
        }
        if (fromIndex < 0) {
            fromIndex = 0;
        }
        if (targetCount == 0) {
            return fromIndex;
        }

        char first = target[targetOffset];
        int max = sourceOffset + (sourceCount - targetCount);

        for (int i = sourceOffset + fromIndex; i <= max; i++) {
            /* Look for first character. */
            if (source[i] != first) {
                while (++i <= max && source[i] != first);
            }

            /* Found first character, now look at the rest of v2 */
            if (i <= max) {
                int j = i + 1;
                int end = j + targetCount - 1;
                for (int k = targetOffset + 1; j < end && source[j]
                        == target[k]; j++, k++);

                if (j == end) {
                    /* Found whole string. */
                    return i - sourceOffset;
                }
            }
        }
        return -1;
    }
复制代码

我々は(INT targetOffset、INT targetCount、INTたfromIndex CHAR []ソース、INT sourceOffset、INT sourceCount、CHAR []ターゲット)は静的メソッドIndexOf内部呼び出し、見ることができ、左から右へ渡すパラメータは、として理解することができますソースバイト配列(最初の文字列のタイトル)、ソース・バイト配列のオフセット(デフォルト0着信内部コール)、バイトのソース配列の長さは、(第2のヘッダを探すためにバイト配列文字列)、バイトは、(まだ0)を探すためにバイト配列、およびインデックスマッチした初期位置の長さを見つけるために、配列のオフセット。

内部に進むには、プロセスは、一般的に見ることができます。

  1. 基準フィルタに違法
  2. 検索するバイト配列の最初の要素を取得し、アレイの上記第1マッチング部材(〜比較について本明細書で一緒に発現)ソース最大バイト配列インデックスを見つけるために計算することができます
  3. オープンサイクルは、最初の位置は、実際にこの方法を最後のパラメータを呼び出すときに渡され、サイクルシンボルの終わりには、私は、ステップ2で最大値を超えています
  4. 迅速に一致する最初の文字の位置を見つけます
  5. オープン内部ループ、出発点としてステップ4で得られた位置、文字の配列の残りの要素を見つけるための迅速なマッチング、完全一致が返される私は、この内側ループの終わりと一致しない、外部ループ、に第一層循環;
  6. 最終的には見つからないか-1されませんでした

類似してカーソルプログラムの作者で始まる、実際には、その内部の原則を調査したが、より微妙な、特にフロー制御文、非常に洗練された臨界値の使用は、それは価値の学習です!

それをこの共有のためにすべてのことですが、学生を歓迎するために間違った場所が私を修正何かがそこにあります!

おすすめ

転載: juejin.im/post/5e8c37d551882573a509a40d