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

守給你的承諾、 提交于 2020-06-13 09:23:25

问题


This question has been asked and answered plenty of times before. However, I'm specifically asking for the substrings to be printed in the specific order by each letter as shown in the output.

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
}

The output below is correct. It prints all possible substrings in the desired order. This is the desired order, but the code can't be hard-coded.

OUTPUT:

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

While this technically works, it's clearly hard coded and therefore only works for words up to around 8 letters or less. The following code below is a refactored version of breakWordIntoPieces() utilizing all other methods above.

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);
        }
    }
}

OUTPUT:

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

I think there's something important with that -2 in the error code. I think it has to do with subtracting more letters to a string than the length of the string itself?


回答1:


You can use two for loops for this, one nested inside the other. The outer loop moves in from the left, the inner loop moves in from the right.

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();
    }
}

For printPieces("ABIGWORD", 2) we get:

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



回答2:


In my code I kept a temp with the value of my String before I printed it backwards (which requires to sub-string).
After printing it backwards I returned to the original String and called the function recursively without the first char.

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()));
    }
}


来源:https://stackoverflow.com/questions/61332162/print-all-the-combination-of-substrings-from-a-given-string-in-order-by-letter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!