我必须读取一个整数,它将是后续行的长度。 (文本行永远不会超过提供的长度。)
然后我必须阅读每行文本并尽可能均匀地将空格转换为下划线。例如:
我输入的行长为30.然后是一行文字Hello this is a test string
。然后将所有空格转换为下划线并填充,以便文本填充给定的行长度,如下所示:Hello__this__is__a_test_string
。如您所见,原始文本的长度为27个字符,因此要将其填充为30个字符,我必须在原始文本中添加3个额外的空格,然后将这些空格转换为下划线字符。
请你告诉我一个可以解决这个问题的方法吗?
答案 0 :(得分:6)
我所做的是将句子分成单词。然后计算出需要添加多少空格。然后迭代单词并为每个单词添加一个空格,直到用完要添加的空格。如果你有足够的空格,你需要在单词上添加多个(比如你有5个单词,但需要添加13个空格),只需将剩余的空格数除以单词数,然后将每个单词的数字加到每个单词中。先说。然后你可以取余数并迭代添加空格的单词,直到你完成为止。另外,请确保只向句子中的最后一个单词添加空格。
答案 1 :(得分:4)
我最近必须在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;
我这样做的方法是将字符串转换为子字符串数组,子字符串是数组中的每个字。如果你在javadoc中查找String类,你应该找到你可以用来实现这个的String类中的方法!
如果有了子串数组,则可以在每个子字符串的末尾添加空格字符串以形成新的子字符串!
这又是一个简单的计算。使用%运算符,您可以执行类似于我们之前所做的除法的余数除法。
noofgaps % noofspacestoadd = noofspacestoaddtoeachgap;
此计算的结果为我们提供了证明文本合理所需的额外空格数。
这可能是算法中最困难的部分,因为你必须找出一种迭代单词之间每个间隙的方法,并添加一个额外的空格,直到没有剩余空间来添加!
return String;
答案 2 :(得分:1)
让我们尝试解决问题:
从30减去字符串的长度 - 这是你在某处添加的额外空格的数量(在这种情况下为3)。
计算现有空格的数量(本例中为5)。
现在你知道你需要尽可能均匀地将第一批额外空格分配到现有空格中(在这种情况下,将3分配到5)。
想想你如何在现实生活中分发这样的东西,比如把球分到水桶里。你可能会在你的水桶中旋转,在每个水桶中丢球,直到你用完为止。那么请考虑如何在java代码中实现这一点(提示:查看不同类型的循环)。
答案 3 :(得分:1)
我要做的就是使用带有正则表达式替换的循环。
在进行初始替换之后,我建议你使用while循环,限制字符串的长度小于目标大小。在一段时间内初始化int numUnderscores = 1;
。然后循环中的步骤将是:
"/[^_](_{" + numUnderscores + "})[^_]/"
,它表示“任何不是下划线的字符,后跟下划线字符的numUnderscores实例,后跟任何不是下划线的字符”.ReplaceFirst()
以执行更换numUnderscores
显然,由于这是一个家庭作业问题,我将离开实际编写代码的过程作为练习。如果您对其中某些部分或我所描述的逻辑结构的某些组成部分有具体问题,请在评论中提问!
以这种方式做事的好处是它可以适用于任何大小的字符串,并且可以根据不同的情况进行配置。
答案 4 :(得分:1)
这个问题最难的是定义“尽可能均匀”。
你的例子:
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.
}
}
答案 5 :(得分:1)
我写了一个简单的方法来证明文本。它不是100%准确,但大部分都有效(因为它完全忽略了标点符号,并且可能还有一些边缘情况丢失)。 此外,Word以更丰富的方式证明文本(通过不添加空格来填补空白,但均匀分布空白的宽度,这在这里很难处理。)
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);
}
答案 6 :(得分:1)
您只需要调用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();
}
以下是maxWidth为 80 个字符的示例转换: 以下段落完全包含 115 个单词,并且花费了 55 ms 来将转换后的文本写入外部文件。 / p>
我已经测试了这段代码中大约 70k + 个单词的段落,大约花了 400 ms 来将转换后的文本写到文件。
输入
这些特征倾向于使法律写作正式化。这种手续可以 采取长句,复杂结构,过时和 超形式的词汇,并且注重内容以排除 读者需求。法律写作中的某些手续是必要的, 鉴于某些法律文件的重要性以及 某些法律文件所处情况的严重性 用过的。但是,并非所有法律写作形式都是合理的。到 形式产生不透明和不精确的程度是 不受欢迎的。在某种程度上妨碍了形式的读者 理解,这是不太理想的。特别是法律内容 必须传达给非律师,手续应让清 交流。
输出
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.
答案 7 :(得分:1)
我遵循了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();
}
}
请注意,我还注释了每个段落的最后一行(在getLeftJustifiedLine中)的空格填充,并使方法静态化。.
答案 8 :(得分:0)
this presentation的第一部分包含用于文本对齐的动态编程算法。