首页 > 解决方案 > 即使达到该行的最大限制,如何不跨行拆分单词?

问题描述

我试图将文本向左对齐,其中每行输入的字符数最多,如果单词的字符超过总数,我希望它打印在同一行而不是跨行拆分。

输入:`String[] 段落 = FileUtil.readFile("C:\Users\Desktop\test_pratchett.txt"); String sampleText = Arrays.toString(paragraphs);

System.out.println(util.format(sampleText));`

主要代码:

private int maxChars;
private String alignment; 
private int charsAdded = 0;

public StringAlignUtils(String alignmentType ,int maxChars) {
    this.alignment = alignmentType; 
    
    if (maxChars < 0) {
        throw new IllegalArgumentException("maxChars must be positive.");
    }
    this.maxChars = maxChars;
}

public StringBuffer format(Object input, StringBuffer where, FieldPosition ignore) {
    String s = input.toString();
    List<String> strings = splitInputString(s);
    ListIterator<String> listItr = strings.listIterator();

    while (listItr.hasNext()) 
    {
        String wanted = listItr.next();
       // System.out.println("Wanted 1: "+ wanted);
         
        //Get the spaces in the right place.
        switch (alignment) 
        {
            
            case "L":
                 //System.out.println("Where 2: "+ where);
                 //System.out.println("Wanted 2: "+ wanted);
                where.append(wanted);
                 //System.out.println("Wanted 3: "+ wanted);
                 //System.out.println("Where 3: "+ where);
                //pad(where, maxChars - wanted.length());
                break;
                
            
            }
            where.append("\n");
    }
    return where;
}


protected final void pad(StringBuffer to, int howMany)
  { 
      for (int i = 0; i <howMany; i++) 
      to.append(' '); 
        
 }


String format(String s) {
    return format(s, new StringBuffer(), null).toString();
}

public Object parseObject(String source, ParsePosition pos) {
    return source;
}

private List<String> splitInputString(String str) {
    System.out.println("Str: "+str);
    List<String> list = new ArrayList<String>();
    ArrayList<String> tempList = new ArrayList<String>();
    ArrayList<String> addWordsList = new ArrayList<String> ();
    
            
    if (str == null)
        return list;
    
    
    /*
     * System.out.println("SplitInputString: "+str); // String split[] =
     * str.split(" ?(?<!\\G)((?<=[^\\p{Punct}])(?=\\p{Punct})|\\b) ?"); String
     * split[] = str.split(" "); tempList.addAll(Arrays.asList(split));
     * System.out.println("Temp List: "+tempList);
     * 
     * for(int i=0; i< tempList.size(); i++) { String word = tempList.get(i); int
     * wordLength = word.length(); charsAdded = charsAdded + wordLength;
     * if(charsAdded <maxChars) { addWordsList.add(word);
     * 
     * } System.out.println("AddWordsList: "+addWordsList);
     * 
     * }
     */
    
    
      for (int i = 0; i < str.length(); i+= maxChars) {
          
    int endindex = Math.min(i + maxChars, str.length()); 
      String tempString = str.substring(i, endindex).trim();
      
      list.add(tempString); //trim removes leading spaces
      System.out.println("List: "+list);
      
      }
     
     
     
    return list;

我的输出:(如果最大字符数为 80)

  1. 看不见的大学发生了很多事情,遗憾的是教学不得不
  2. 其中之一。教师们早就面对这个事实,并完善了 va
  3. 用于避免它的各种设备。

预期输出:

  1. 看不见的大学发生了很多事情,遗憾的是教学不得不
  2. 其中之一。教师们早就面对这个事实,并完善了各种
  3. 避免它的设备。

标签: javaarraysstringarraylistsplit

解决方案


您要避免的一件事是多次处理这些行。这意味着将它们读入,转换为长字符串或缓冲区,并根据所需长度进行格式化。这是低效的。我建议一次读取一个字符(因为它是缓冲输入,这并不昂贵)并将行构建到所需的长度。

这工作如下:

  • 使用 try with-resources 打开文件进行阅读。
  • 读入一个字符。
    • 如果是新行 ( \n),请用空格替换。
    • 如果是返回,(\r),忽略它并继续下一个字符
  • 如果StringBuilder是所需的长度并且当前字符是空白,则修剪空白,打印它,然后重置StringBuilder.
  • 然后将当前字符附加到缓冲区。
  • 继续直到文件中没有更多字符
  • StringBuilder如果它包含字符,则打印当前。
String inputFile = "...your input file...";
try (BufferedReader br = new BufferedReader(new FileReader(
        inputFile))) {
    int lineSize = 80;
    StringBuilder sb = new StringBuilder();
    int ch;
    int lineNo = 1;
    while ((ch = br.read()) != -1) {
        if (ch == '\n') {
            ch = ' ';
        }
        if (ch == '\r') {
            continue;
        }
        if (sb.length() >= lineSize && ch == ' ') {
            System.out.printf("%2d. %s%n", lineNo++, sb.toString().trim());
            sb.setLength(0);
        }
        sb.append((char) ch);
    }
    String last = sb.toString();
    if (!last.isBlank()) {
        System.out.printf("%2d. %s%n", lineNo, sb.toString().trim());
    }
} catch (IOException ie) {
    ie.printStackTrace();
}

给出一个包含以下行的文件。

Many things went on at the
Unseen University and, regrettably
teaching had to be one of them. The
faculty had long ago confronted this
fact and had perfected various
devices for avoiding it.

这是打印的内容

 1. Many things went on at the Unseen University and, regrettably teaching had to be
 2. one of them. The faculty had long ago confronted this fact and had perfected various
 3. devices for avoiding it.

推荐阅读