按字母顺序打印给定字符串的所有子字符串组合

Print all the combination of substrings from a given string in order by letter

这个问题已经被问过 很多次了。但是,我特别要求按每个字母的特定顺序打印子字符串,如输出中所示。

import java.util.*;

public static void main(String[] args)
{
    breakWordIntoPieces("ABIGWORD");    
}  

public static void breakWordIntoPieces(String str)
{
    if (str.length() > 1) // I'm skipping all substrings of less than 2 letters
    {

        List<String> fragments = breakWordIntoPiecesFromRightToLeft(str);

        for (String fragment : fragments) // I'm using the variable name "fragments" as 
                                          // another word for "substring".
        {
            System.out.print("\n" + fragment);
        }
    }
    System.out.print("\n");

    str = removeFirstChar(str, 1);
    List<String> fragments2 = breakWordIntoPiecesFromRightToLeft(str);

    for (String fragment : fragments2)
    {
        System.out.print("\n" + fragment);
    }

    if (str.length() > 1)
    {
        str = removeFirstChar(str, 1);
        List<String> fragments3 = breakWordIntoPiecesFromRightToLeft(str);

        System.out.print("\n");

        for (String fragment : fragments3)
        {
            System.out.print("\n" + fragment);
        }
    }

    if (str.length() > 1)
    {
        str = removeFirstChar(str, 1);
        List<String> fragments4 = breakWordIntoPiecesFromRightToLeft(str);

        System.out.print("\n");

        for (String fragment : fragments4)
        {
            System.out.print("\n" + fragment);
        }
    }

    if (str.length() > 1) 
    {

        str = removeFirstChar(str, 1);
        List<String> fragments5 = breakWordIntoPiecesFromRightToLeft(str);

        System.out.print("\n");

        for (String fragment : fragments5)
        {
            System.out.print("\n" + fragment);
        }
    }


    if (str.length() > 1)
    {
        str = removeFirstChar(str, 1);
        List<String> fragments6 = breakWordIntoPiecesFromRightToLeft(str);

        System.out.print("\n");

        for (String fragment : fragments6)
        {
            System.out.print("\n" + fragment);
        }
    }

    if (str.length() > 1)
    {
        str = removeFirstChar(str, 1);
        List<String> fragments7 = breakWordIntoPiecesFromRightToLeft(str);
        System.out.print("\n");
        for (String fragment : fragments7)
        {
            System.out.print("\n" + fragment);
        }
    }

    if (str.length() > 1)
    {
        str = removeFirstChar(str, 1);
        List<String> fragments8 = breakWordIntoPiecesFromRightToLeft(str);

        System.out.print("\n");

        for (String fragment : fragments8)
        {
            System.out.print("\n" + fragment);
        }
    }
}

public static List<String> breakWordIntoPiecesFromRightToLeft(String word)
{
    int sizeOfWord = word.length();
    List<String> fragments = new ArrayList<>();

    for (int i = 0; i < word.length() - 1; i++)
    {
         String aFragment = removeLastChar(word, i);
         fragments.add(aFragment);
    }

    return fragments;
}

private static String removeLastChar(String str, Integer i)

{
    return str.substring(0, str.length() - i); //((Line 200)) remove last i letters.
}

public static String removeFirstChar(String s, Integer i)
{
    return s.substring(i); // remove first i letters
}

下面的输出是正确的。它以所需的顺序打印所有可能的子字符串。这是所需的顺序,但代码不能硬编码。

输出:

ABIGWORD //First it prints the whole word.
ABIGWOR  //Then the rest below are all possible sub strings lined up in order by letter
ABIGWO
ABIGW
ABIG
ABI
AB

BIGWORD
BIGWOR
BIGWO
BIGW
BIG
BI

IGWORD
IGWOR
IGWO
IGW
IG

GWORD
GWOR
GWO
GW

WORD
WOR
WO

ORD
OR

RD

虽然这在技术上可行,但它显然是硬编码的,因此仅适用于不超过 8 个字母的单词。以下代码是使用上述所有其他方法的 breakWordIntoPieces() 的重构版本。

public static void breakWordIntoPiecesRefactored(String str)
{
    int subtractCharactersBy = 0;
    int lengthOfWord = str.length();

    while (lengthOfWord > 1) //this if can be checked as the method is called
    {
        str = removeFirstChar(str, subtractCharactersBy); // ((Line 259) 
        lengthOfWord -= 1;
        subtractCharactersBy +=1;
        List<String> fragments = breakWordIntoPiecesFromRightToLeft(str);

        for (String fragment : fragments)
        {
            System.out.print("\n" + fragment);
        }
    }
}

输出:

ABIGWORD
ABIGWOR
ABIGWO
ABIGW
ABIG
ABI
AB
BIGWORD
BIGWOR
BIGWO
BIGW
BIG
BI
GWORD //Why is it skipping the letter I straight to G?
GWOR
GWO
GW
RD

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out 
of range: -2
at java.lang.String.substring(String.java:1931)
at com.company.Controllers.SpellCheck.removeFirstChar(SpellCheck.java:200)
at 
com.company.Controllers.SpellCheck.breakWordIntoPiecesRefactored(SpellCheck.java:259)
at com.company.Main.main(Main.java:20)

Process finished with exit code 1

我认为错误代码中的 -2 很重要。我认为这与从字符串中减去比字符串本身的长度更多的字母有关?

在我的代码中,我在向后打印它之前用我的字符串值保存了一个临时值(这需要子字符串)。
向后打印后,我返回到原始字符串并在没有第一个字符的情况下递归调用该函数。

public static void printSO(String word)
{
    if (word.length()>1) {
        String temp = word;
        while (word.length()>1) {
            System.out.println(word.substring(0, word.length()));
            word = word.substring(0,word.length()-1);   
        }
        System.out.println("\t"); //gap
        word = temp;
        printSO(word.substring(1,word.length()));
    }
}

您可以为此使用两个 for 循环,一个嵌套在另一个循环中。外环从左进,内环从右进

static void printPieces(String str, int min)
{
    for(int i=0; i<=str.length()-min; i++)
    {
        for(int j=str.length(); j>=i+min; j--)
        {
            System.out.println(str.substring(i, j));
        }
        System.out.println();
    }
}

对于printPieces("ABIGWORD", 2),我们得到:

ABIGWORD
ABIGWOR
ABIGWO
ABIGW
ABIG
ABI
AB

BIGWORD
BIGWOR
BIGWO
BIGW
BIG
BI

IGWORD
IGWOR
IGWO
IGW
IG

GWORD
GWOR
GWO
GW

WORD
WOR
WO

ORD
OR

RD