通过添加空格来创建等大小的字符串

时间:2015-05-23 11:41:48

标签: java string

我有一个字符串列表。我想制作相同长度的所有琴弦。 到目前为止我尝试过的是

    int largestLineLength = 0;

    for(int i=0;i<list.size();i++){
        String s = list.get(i);
        list.remove(s)
        list.add(s.trim());
    }
    //get the largest line
    for (String s : list) {
        int length = s.trim().length();
        if (length > largestLineLength) {
            largestLineLength = length;
        }
    }

    for(String s: list){
        while(s.length() != largestLineLength){
            //add spaces to s
        }
    }

要求:

  1. 通过添加空格使所有线条具有相同的长度 之间的话。
  2. 在该行之前或之后不应添加任何空格。
  3. 应均匀分布空格以使所有线条相等
  4. 例如

    Luke Skywalker has returned 
    to his home planet of Tatooine 
    in order to — okay, you 
    know what, we don't care. 
    We were thinking of not even 
    doing this one. 
    

    应该是

    Luke  Skywalker  has  returned 
    to his home planet of Tatooine 
    in   order  to  —   okay,  you 
    know   what,  we  don't  care. 
    We  were  thinking of not even 
    doing this one. 
    

    P.S。最后一行是例外

2 个答案:

答案 0 :(得分:1)

一个简单的解决方案是找出最长线和当前线之间的差异。找出你队伍中的每一个字,然后在每个世界之后分配你的空间。

我已经实施了这个解决方案,并且可以在线查看here看看我的解决方案:

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();

    list.add("Luke Skywalker has returned");
    list.add("to his home planet of Tatooine");
    list.add("in order to — okay, you");
    list.add("know what, we don't care.");
    list.add("We were thinking of not even");
    list.add("doing this one.");

    int largestLineLength = 0;

    for (String s : list) {
        int length = s.length();
        if (length > largestLineLength) {
            largestLineLength = length;
        }
    }

    List<String> outputs = new ArrayList<String>();

    for (String s : list.subList(0, list.size() - 1)) {

        int needSpace = largestLineLength - s.length();
        if (needSpace > 0) { //check if we need space in this line.
            String[] words = s.split(" "); //find words in the line
            int index = 0;

            StringBuilder[] stringBuilders = new StringBuilder[words.length];

            for (int i = 0; i < words.length - 1; i++) {
                stringBuilders[i] = new StringBuilder(words[i]);
                stringBuilders[i].append(" ");
            }

            stringBuilders[words.length - 1] = new StringBuilder(words[words.length - 1]);

            while (needSpace > 0) { //add spaces and decrease needSpace until it reaches zero.
                stringBuilders[index].append(" "); //add space to the end of every world in order
                index = index == words.length - 2 ? 0 : index + 1; //words-2 is because we didnt want any spaces after last word of line.
                needSpace--;
            }

            StringBuilder stringBuilder = new StringBuilder();

            for (int i = 0; i < words.length; i++) {
                stringBuilder.append(stringBuilders[i]);
            }


            s = stringBuilder.toString();
        }
        outputs.add(s);
    }
    outputs.add(list.get(list.size()-1));

    for(String s : outputs){
        System.out.println(s);
    }
}
Luke  Skywalker  has  returned
to his home planet of Tatooine
in   order   to  —  okay,  you
know   what,  we  don't  care.
We  were  thinking of not even
doing this one.

答案 1 :(得分:1)

首先要做的是找到所需的确切空间数。

然后你可以做一个Bresenham算法的变体来计算每个单词后插入的空格数,而不需要求助于浮点运算。单词之间有numberofWords - 1个空格,所以:

nSpaces / (numberofWords - 1 - wordPos)

计算已插入的空格数(nPad)并插入

nSpaces / (numberofWords - 1 - wordPos) - nPad 

当前单词之后的空格。

我确信有更优雅的方式来完成它,但作为初始版本:

    final String[] lines = {
        "Luke Skywalker has returned",
        "to his home planet of Tatooine",
        "in order to — okay, you",
        "know what, we don't care.",
        "We were thinking of not even",
        "doing this one."
    };

    int maxLength = 0;
    for (String line: lines) {
        maxLength = Math.max(line.length(), maxLength);
    }

    final List<String> paddedLines = new ArrayList<>();
    for (String line: lines) {
        String[] words = line.split("\\s+");
        int wordsLength = 0;
        for (String word: words) {
            wordsLength += word.length();
        }
        int nSpaces = maxLength - wordsLength;

        final StringBuilder sb = new StringBuilder();
        int nPad = 0;
        for (int i = 0; i < words.length; ++i) {
            String word = words[i];
            sb.append(word);
            if (i < words.length - 1) {
                sb.append(' ');
                ++nPad;
                for (; nPad <= (nSpaces / (words.length - 1 - i)); ++nPad) {
                    sb.append(' ');
                }
            }
        }
        paddedLines.add(sb.toString());
    }

受到一些分配问题的困扰,但似乎完成了工作:

Luke   Skywalker has   returned
to  his home planet of Tatooine
in   order to —  okay,      you
know   what, we don't     care.
We  were thinking of not   even
doing         this         one.

为了获得更好的体验,我们可以使用适当的舍入而不是整数除法:

            for (; nPad <= Math.round(nSpaces / (double)(words.length - 1 - i)); ++nPad) {
                sb.append(' ');
            }

这会产生

Luke   Skywalker has   returned
to  his home planet of Tatooine
in   order to —  okay,      you
know   what, we  don't    care.
We  were thinking of not   even
doing          this        one.

仍然不完美,但更好。