问题
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