Спасибо за публикацию, мне нравятся такие проблемы.
Как уже упоминалось выше, здесь есть небольшая проблема в том, что вы не знаете, сколько строк требуется.Таким образом, вы не знаете, разрешить ли 2 (или более) цифр для номера сообщения / общего количества сообщений.Кроме того, не могли бы вы использовать шестнадцатеричное (для 16 сообщений требуется одна цифра или даже номер формата 62) (0–9, затем AZ, а затем AZ)?
Можно, конечно, использовать предположение и сказать, есливвод больше, скажем, 200 символов, тогда вы можете использовать двузначный номер сообщения, но если сообщение было одной буквой, за которой повторяется один пробел 100 раз, то вы, вероятно, могли бы избежать использования однозначных номеров сообщений.
Итак, вы можете обнаружить, что вам нужно запустить алгоритм пару раз. Я буду считать, что для этой проблемы приемлем однозначный номер сообщения, вы можете усовершенствовать мое решение, используя базовые 52 номера сообщений.если вам нравится.
Мой подход использует 2 класса:
- Создайте класс MessageLine, представляющий одну строку сообщения.
- MessageSender - класс, который собираетMessageLine (s). Имеет вспомогательный метод, который обрабатывает сообщение и возвращает список MessageLines.
Вот мав классе MessageSender.Если вы запустите его, вы можете передать сообщение в командной строке для его обработки.
package com.gtajb.stackoverflow;
import java.util.LinkedList;
public class MessageSender {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Please supply a message to send");
System.exit(1);
}
// Collect the command line parameters into a single string.
StringBuilder sb = new StringBuilder();
boolean firstWord = true;
for (String s: args) {
if (!firstWord) {
sb.append(" ");
}
firstWord = false;
sb.append(s);
}
// Process the input String and create the MessageSender object.
MessageSender ms = new MessageSender(sb.toString());
System.out.println("Input message: " + sb.toString());
// Retrieve the blocked message and output it.
LinkedList<MessageLine> msg = ms.getBlockedMessage();
int lineNo = 0;
for (MessageLine ml : msg) {
lineNo += 1;
System.out.printf("%2d: %s\n", lineNo, ml.getFormattedLine(msg.size()));
}
}
private String msg;
public MessageSender(String msg) {
this.msg = msg;
processMessage();
}
private LinkedList<MessageLine> blockedMessage = new LinkedList<MessageLine> ();
public LinkedList<MessageLine> getBlockedMessage() {
return blockedMessage;
}
private static final int LINE_MAX_SIZE = 30;
/**
* A private helper method that processes the supplied message when
* the object is constructed.
*/
private void processMessage() {
// Split the message into words and work out how long the message is.
String [] words = msg.split("\\s+");
int messageLength = 0;
for (String w: words) {
messageLength += w.length();
}
messageLength += words.length - 1; // Add in the number of words minus one to allow for the single spaces.
// Can we get away with a single MessageLine?
if (messageLength < LINE_MAX_SIZE) {
// A single message line is good enough.
MessageLine ml = new MessageLine(1);
blockedMessage.add(ml);
for (String w: words) {
ml.add(w);
}
} else {
// Multiple MessageLines will be required.
int lineNo = 1;
MessageLine ml = new MessageLine(lineNo);
blockedMessage.add(ml);
for (String w: words) {
// check if this word will blow the max line length.
// The maximum number of lines is 2. It can be anything that is > 1.
if (ml.getFormattedLineLength(2) + w.length() + 1 > LINE_MAX_SIZE) {
// The word will blow the line length, so create a new line.
lineNo += 1;
ml = new MessageLine(lineNo);
blockedMessage.add(ml);
}
ml.add(w);
}
}
}
}
и вот класс Message Line:
package com.gtajb.stackoverflow;
import java.util.LinkedList;
public class MessageLine extends LinkedList<String> {
private int lineNo;
public MessageLine(int lineNo) {
this.lineNo = lineNo;
}
/**
* Add a new word to this message line.
* @param word the word to add
* @return true if the collection is modified.
*/
public boolean add(String word) {
if (word == null || word.trim().length() == 0) {
return false;
}
return super.add(word.trim());
}
/**
* Return the formatted message length.
* @param totalNumLines the total number of lines in the message.
* @return the length of this line when formatted.
*/
public int getFormattedLineLength(int totalNumLines) {
return getFormattedLine(totalNumLines).length();
}
/**
* Return the formatted line optionally with the line count information.
* @param totalNumLines the total number of lines in the message.
* @return the formatted line.
*/
public String getFormattedLine(int totalNumLines) {
boolean firstWord = true;
StringBuilder sb = new StringBuilder();
for (String w : this) {
if (! firstWord) {
sb.append (" ");
}
firstWord = false;
sb.append(w);
}
if (totalNumLines > 1) {
sb.append (String.format(" (%d/%d)", lineNo, totalNumLines));
}
return sb.toString();
}
}
Я проверил ваши сценарии ипохоже, он дает правильный результат.
Дайте мне знать, если мы получим работу.: -)