Вывести все комбинации подстрок из заданной строки по порядку буквой - PullRequest
0 голосов
/ 21 апреля 2020

Этот вопрос задавался и отвечал много раз раньше. Однако я специально прошу печатать подстроки в указанном порядке c по каждой букве, как показано в выводе.

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

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

Я думаю, что с ошибкой -2 есть что-то важное в ошибке код. Я думаю, что это связано с вычитанием большего количества букв в строку, чем длина самой строки?

Ответы [ 2 ]

2 голосов
/ 21 апреля 2020

Для этого вы можете использовать две петли for, одна вложенная в другую. Внешний l oop движется слева, внутренний l oop движется справа.

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
2 голосов
/ 21 апреля 2020

В моем коде я держал temp со значением моей String, прежде чем печатать его задом наперед (что требует подстроки).
После печати назад я вернулся к исходной строке и рекурсивно вызвал функцию без первого символа.

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