之后我需要读取每一行文本,并尽可能均匀地将其中的空格转换为下划线。例如:
我输入了30作为行长度,然后输入了一行文本"Hello this is a test string"。然后所有的空格都将被转换为下划线,并进行填充,使文本填满给定的行长度,像这样:
Hello__this__is__a_test_string
。如您所见,原始文本长度为27个字符,所以为了将其填充到30个字符,我不得不向原始文本添加3个额外的空格,然后将这些空格转换为下划线字符。请问我该如何处理这个问题?
Hello__this__is__a_test_string
。如您所见,原始文本长度为27个字符,所以为了将其填充到30个字符,我不得不向原始文本添加3个额外的空格,然后将这些空格转换为下划线字符。最近我在Java中做了一件类似的事情。代码本身相对来说比较简单。我发现最花时间的是理解调整文本的过程。
我开始制定手动调整文本的逐步过程。
这样做让我编写算法变得更容易了!
你说你已经读取了行长度和行上的文本,所以1和2你已经完成了。其中第2步使用了一个简单的string.length()
调用。
计算需要添加到字符串中以使其与行长度相等的空格数,只需将行长度减去字符串长度即可。
lineLength - string.length() = noofspacestoadd;
有很多方法可以做到这一点。我发现最简单的方法是将字符串转换为char[],然后迭代字符并检查是否为“”,如果确实找到一个“”,则设置一个计数。
这是一个简单的除法计算!
noofgaps / noofspacestoadd = noofspacestoaddtoeachgap;
注意:您必须确保使用整数进行此除法!由于5/2 = 2.5,因此您知道必须在每个单词之间的空格中添加2个空格,并且使用int进行的除法会将小数截断形成一个整数。
在能够添加所需字符串以填充每个空隙之前,您需要将此数字转换为等于该给定数字的空格字符串。因此,您需要编写一种将给定整数转换为相应数量的空格字符串的方法。同样,可以用不同的方式完成此操作。我所做的方式是这样的:
String s = "";
for(int i=noofspacestoaddtoeachgap; i>0; i--)
{
s+= " ";
}
return s;
noofgaps % noofspacestoadd = noofspacestoaddtoeachgap;
这个计算结果告诉我们需要添加多少额外的空格来使文本对齐。
这可能是该算法最困难的部分,因为您需要想出一种迭代每个单词之间的间隔并添加额外空格的方法,直到没有更多的额外空格可以添加!
return String;
fullJustify()
方法,其中需要传递单词列表以及你想要输出的每行最大宽度。public List<String> fullJustify(String[] words, int maxWidth) {
int n = words.length;
List<String> justifiedText = new ArrayList<>();
int currLineIndex = 0;
int nextLineIndex = getNextLineIndex(currLineIndex, maxWidth, words);
while (currLineIndex < n) {
StringBuilder line = new StringBuilder();
for (int i = currLineIndex; i < nextLineIndex; i++) {
line.append(words[i] + " ");
}
currLineIndex = nextLineIndex;
nextLineIndex = getNextLineIndex(currLineIndex, maxWidth, words);
justifiedText.add(line.toString());
}
for (int i = 0; i < justifiedText.size() - 1; i++) {
String fullJustifiedLine = getFullJustifiedString(justifiedText.get(i).trim(), maxWidth);
justifiedText.remove(i);
justifiedText.add(i, fullJustifiedLine);
}
String leftJustifiedLine = getLeftJustifiedLine(justifiedText.get(justifiedText.size() - 1).trim(), maxWidth);
justifiedText.remove(justifiedText.size() - 1);
justifiedText.add(leftJustifiedLine);
return justifiedText;
}
public static int getNextLineIndex(int currLineIndex, int maxWidth, String[] words) {
int n = words.length;
int width = 0;
while (currLineIndex < n && width < maxWidth) {
width += words[currLineIndex++].length() + 1;
}
if (width > maxWidth + 1)
currLineIndex--;
return currLineIndex;
}
public String getFullJustifiedString(String line, int maxWidth) {
StringBuilder justifiedLine = new StringBuilder();
String[] words = line.split(" ");
int occupiedCharLength = 0;
for (String word : words) {
occupiedCharLength += word.length();
}
int remainingSpace = maxWidth - occupiedCharLength;
int spaceForEachWordSeparation = words.length > 1 ? remainingSpace / (words.length - 1) : remainingSpace;
int extraSpace = remainingSpace - spaceForEachWordSeparation * (words.length - 1);
for (int j = 0; j < words.length - 1; j++) {
justifiedLine.append(words[j]);
for (int i = 0; i < spaceForEachWordSeparation; i++)
justifiedLine.append(" ");
if (extraSpace > 0) {
justifiedLine.append(" ");
extraSpace--;
}
}
justifiedLine.append(words[words.length - 1]);
for (int i = 0; i < extraSpace; i++)
justifiedLine.append(" ");
return justifiedLine.toString();
}
public String getLeftJustifiedLine(String line, int maxWidth) {
int lineWidth = line.length();
StringBuilder justifiedLine = new StringBuilder(line);
for (int i = 0; i < maxWidth - lineWidth; i++)
justifiedLine.append(" ");
return justifiedLine.toString();
}
These features tend to make legal writing formal. This formality can take the
form of long sentences, complex constructions, archaic and hyper-formal
vocabulary, and a focus on content to the exclusion of reader needs. Some of
this formality in legal writing is necessary and desirable, given the importance
of some legal documents and the seriousness of the circumstances in which some
legal documents are used. Yet not all formality in legal writing is justified.
To the extent that formality produces opacity and imprecision, it is
undesirable. To the extent that formality hinders reader comprehension, it is
less desirable. In particular, when legal content must be conveyed to
nonlawyers, formality should give way to clear communication.
让我们试着将问题分解:
从30中减去字符串的长度 - 这就是你需要添加的额外空格数(在这种情况下为3)。
计算现有空格的数量(在这种情况下为5)。
现在你知道你需要尽可能均匀地将第一个额外空格数分配到现有空格中(在这种情况下,将3个分配到5个中)。
想象一下在现实生活中如何分配类似的东西,比如把球放进桶里。你可能会轮流使用桶,每个桶放一个球,直到用完为止。因此,请考虑如何在你的Java代码中实现这一点(提示:查看不同类型的循环)。
我会使用带有正则表达式替换的循环来完成这个任务。
在进行初始替换后,建议使用while循环,其边界是字符串长度小于目标大小。在while之外初始化int numUnderscores = 1;
。然后循环内的步骤将是:
“/ [^ _] (_ {”+ numUnderscores +“}) [^ _] /”
这样的东西,它表示“不是下划线的任何字符,后跟numUnderscores个下划线字符,后跟不是下划线的任何字符”.ReplaceFirst()
来执行替换numUnderscores
显然,由于这是一个作业问题,我将编写代码的实际过程留作练习。如果您对其中的某些部分或我描述的逻辑结构的某些组件有具体问题,请在评论中提问!
这种方法的好处是它适用于任何大小的字符串,并且非常可配置以适应不同的情况。
Hello__this__is__a_test_string
...使所有更长的间隔位于左侧。难道不应该是:
Hello__this_is__a_test__string
...更长的间隙是否均匀地分布在输出字符串中,以更好地适应问题的不精确描述?
然而,让我们解决它,使其给出样本答案。
numNewChars
== lengthWanted
减去 inputString.length()
numGaps
——它是单词数减一。n
或 n+1
个新空格。其中 n
是 numNewChars / numGaps
——整数除法;向下取整。n+1
个新空格而不是 n> 的次数是多少?它是余数:plusOnes = numNewChars % numGaps
这就是您需要的所有数字。现在使用您学习过的任何方法(因为这显然是一个家庭作业问题,您不想使用未在课程中涵盖的语言功能或库),浏览字符串:
- 对于前
plusOnes
个空格,在已有的空格基础上再插入 n+1
个空格。
- 对于其余的空格,在已有的空格基础上再插入
n
个空格。
一个非常基本的方法如下:
String output= "";
for(int i=0; i<input.length(); i++) {
char c = input.charAt(i);
if(c == ' ' {
output += ...; // appropriate number of "_" chars
} else {
output += "" + c; // "" + just turns the char into a String.
}
}
我按照Shahroz Saleem的答案进行操作(但我的声誉值太低而无法评论 :/)-然而,我需要进行一项小更改,因为它没有考虑到超过行长度的单词(例如文本中的URL)。
import java.util.ArrayList;
import java.util.List;
public class Utils {
public static List<String> fullJustify(String words, int maxWidth) {
return fullJustify(words.split(" "), maxWidth);
}
public static List<String> fullJustify(String[] words, int maxWidth) {
int n = words.length;
List<String> justifiedText = new ArrayList<>();
int currLineIndex = 0;
int nextLineIndex = getNextLineIndex(currLineIndex, maxWidth, words);
while (currLineIndex < n) {
StringBuilder line = new StringBuilder();
for (int i = currLineIndex; i < nextLineIndex; i++) {
line.append(words[i] + " ");
}
currLineIndex = nextLineIndex;
nextLineIndex = getNextLineIndex(currLineIndex, maxWidth, words);
justifiedText.add(line.toString());
}
for (int i = 0; i < justifiedText.size() - 1; i++) {
String fullJustifiedLine = getFullJustifiedString(justifiedText.get(i).trim(), maxWidth);
justifiedText.remove(i);
justifiedText.add(i, fullJustifiedLine);
}
String leftJustifiedLine = getLeftJustifiedLine(justifiedText.get(justifiedText.size() - 1).trim(), maxWidth);
justifiedText.remove(justifiedText.size() - 1);
justifiedText.add(leftJustifiedLine);
return justifiedText;
}
public static int getNextLineIndex(int currLineIndex, int maxWidth, String[] words) {
int n = words.length;
int width = 0;
int count = 0;
while (currLineIndex < n && width < maxWidth) {
width += words[currLineIndex++].length() + 1;
count++;
}
if (width > maxWidth + 1 && count > 1)
currLineIndex--;
return currLineIndex;
}
public static String getFullJustifiedString(String line, int maxWidth) {
StringBuilder justifiedLine = new StringBuilder();
String[] words = line.split(" ");
int occupiedCharLength = 0;
for (String word : words) {
occupiedCharLength += word.length();
}
int remainingSpace = maxWidth - occupiedCharLength;
int spaceForEachWordSeparation = words.length > 1 ? remainingSpace / (words.length - 1) : remainingSpace;
int extraSpace = remainingSpace - spaceForEachWordSeparation * (words.length - 1);
for (int j = 0; j < words.length - 1; j++) {
justifiedLine.append(words[j]);
for (int i = 0; i < spaceForEachWordSeparation; i++)
justifiedLine.append(" ");
if (extraSpace > 0) {
justifiedLine.append(" ");
extraSpace--;
}
}
justifiedLine.append(words[words.length - 1]);
for (int i = 0; i < extraSpace; i++)
justifiedLine.append(" ");
return justifiedLine.toString();
}
public static String getLeftJustifiedLine(String line, int maxWidth) {
int lineWidth = line.length();
StringBuilder justifiedLine = new StringBuilder(line);
//for (int i = 0; i < maxWidth - lineWidth; i++)
// justifiedLine.append(" ");
return justifiedLine.toString();
}
}
public static void justifyText (String text) {
int STR_LENGTH = 80;
int end=STR_LENGTH, extraSpacesPerWord=0, spillOverSpace=0;
String[] words;
System.out.println("Original Text: \n" + text);
System.out.println("Justified Text: ");
while(end < text.length()) {
if(text.charAt(STR_LENGTH) == ' ') {
// Technically, this block is redundant
System.out.println (text.substring(0, STR_LENGTH));
text = text.substring(STR_LENGTH);
continue;
}
end = text.lastIndexOf(" ", STR_LENGTH);
words = text.substring(0, end).split(" ");
extraSpacesPerWord = (STR_LENGTH - end) / words.length;
spillOverSpace = STR_LENGTH - end + (extraSpacesPerWord * words.length);
for(String word: words) {
System.out.print(word + " ");
System.out.print((extraSpacesPerWord-- > 0) ? " ": "");
System.out.print((spillOverSpace-- > 0) ? " ": "");
}
System.out.print("\n");
text = text.substring(end+1);
}
System.out.println(text);
}
Hello__th...
示例中,你甚至可以更加均匀:所有添加的空格都在左边,如果你将“__”从“this”和“is”之间移动到“test”和“string”之间,你会得到一个看起来更加“均匀”的东西。我想你并不需要这种程度的均匀性——你只关心是否存在至少一对有一个下划线的单词对,它们之间没有3个下划线。 - flies