使用 StringBuilder 用空格或其他字符填充字符串

Posted

技术标签:

【中文标题】使用 StringBuilder 用空格或其他字符填充字符串【英文标题】:Use StringBuilder to pad String with blank spaces or other characters 【发布时间】:2012-08-06 12:21:32 【问题描述】:

我是 java 初学者,这是我在 *** 上的第一篇文章。尽管我的初始代码与此处的其他帖子相似,但我的问题与实现 StringBuilder 以及此帖子的原因有关。

我已经创建了一个方法

**Initial code**
private static String padAgain(String result,int padNum)  
      
          String str = "";  
          for(int i = padNum; i >= 0; i--)  
          
            str = String.format("%" + padNum + "s", result).replace(" ", "*");  
          
          return str;  
      

使用 String.format 方法在字符串左侧填充空格(或特殊字符)。我在我的程序中使用相同的方法来正确证明数字。数字以 2(一位数)开头,并以 2 的倍数增加(包含 n 个位数),其中空格与位数的增加成反比。

这是用于说明目的的输出:

    Enter exponent value for base-2 - Enter 0 to exit: 
128
Square    1: **************************************2 items
Square    2: **************************************4 items
Square    3: **************************************8 items
Square    4: *************************************16 items
Square    5: *************************************32 items
Square    6: *************************************64 items
Square    7: ************************************128 items
Square    8: ************************************256 items
Square    9: ************************************512 items
Square   10: ***********************************1024 items
Square   11: ***********************************2048 items
Square   12: ***********************************4096 items
Square   13: ***********************************8192 items
Square   14: **********************************16384 items
Square   15: **********************************32768 items
Square   16: **********************************65536 items
Square   17: *********************************131072 items
Square   18: *********************************262144 items
Square   19: *********************************524288 items
Square   20: ********************************1048576 items
Square   21: ********************************2097152 items
Square   22: ********************************4194304 items
Square   23: ********************************8388608 items
Square   24: *******************************16777216 items
Square   25: *******************************33554432 items
Square   26: *******************************67108864 items
Square   27: ******************************134217728 items
Square   28: ******************************268435456 items
Square   29: ******************************536870912 items
Square   30: *****************************1073741824 items
Square   31: *****************************2147483648 items
Square   32: *****************************4294967296 items
Square   33: *****************************8589934592 items
Square   34: ****************************17179869184 items
Square   35: ****************************34359738368 items
Square   36: ****************************68719476736 items
Square   37: ***************************137438953472 items
Square   38: ***************************274877906944 items
Square   39: ***************************549755813888 items
Square   40: **************************1099511627776 items
Square   41: **************************2199023255552 items
Square   42: **************************4398046511104 items
Square   43: **************************8796093022208 items
Square   44: *************************17592186044416 items
Square   45: *************************35184372088832 items
Square   46: *************************70368744177664 items
Square   47: ************************140737488355328 items
Square   48: ************************281474976710656 items
Square   49: ************************562949953421312 items
Square   50: ***********************1125899906842624 items
Square   51: ***********************2251799813685248 items
Square   52: ***********************4503599627370496 items
Square   53: ***********************9007199254740992 items
Square   54: **********************18014398509481984 items
Square   55: **********************36028797018963968 items
Square   56: **********************72057594037927936 items
Square   57: *********************144115188075855872 items
Square   58: *********************288230376151711744 items
Square   59: *********************576460752303423488 items
Square   60: ********************1152921504606846976 items
Square   61: ********************2305843009213693952 items
Square   62: ********************4611686018427387904 items
Square   63: ********************9223372036854775808 items
Square   64: *******************18446744073709551616 items
Square   65: *******************36893488147419103232 items
Square   66: *******************73786976294838206464 items
Square   67: ******************147573952589676412928 items
Square   68: ******************295147905179352825856 items
Square   69: ******************590295810358705651712 items
Square   70: *****************1180591620717411303424 items
Square   71: *****************2361183241434822606848 items
Square   72: *****************4722366482869645213696 items
Square   73: *****************9444732965739290427392 items
Square   74: ****************18889465931478580854784 items
Square   75: ****************37778931862957161709568 items
Square   76: ****************75557863725914323419136 items
Square   77: ***************151115727451828646838272 items
Square   78: ***************302231454903657293676544 items
Square   79: ***************604462909807314587353088 items
Square   80: **************1208925819614629174706176 items
Square   81: **************2417851639229258349412352 items
Square   82: **************4835703278458516698824704 items
Square   83: **************9671406556917033397649408 items
Square   84: *************19342813113834066795298816 items
Square   85: *************38685626227668133590597632 items
Square   86: *************77371252455336267181195264 items
Square   87: ************154742504910672534362390528 items
Square   88: ************309485009821345068724781056 items
Square   89: ************618970019642690137449562112 items
Square   90: ***********1237940039285380274899124224 items
Square   91: ***********2475880078570760549798248448 items
Square   92: ***********4951760157141521099596496896 items
Square   93: ***********9903520314283042199192993792 items
Square   94: **********19807040628566084398385987584 items
Square   95: **********39614081257132168796771975168 items
Square   96: **********79228162514264337593543950336 items
Square   97: *********158456325028528675187087900672 items
Square   98: *********316912650057057350374175801344 items
Square   99: *********633825300114114700748351602688 items
Square  100: ********1267650600228229401496703205376 items
Square  101: ********2535301200456458802993406410752 items
Square  102: ********5070602400912917605986812821504 items
Square  103: *******10141204801825835211973625643008 items
Square  104: *******20282409603651670423947251286016 items
Square  105: *******40564819207303340847894502572032 items
Square  106: *******81129638414606681695789005144064 items
Square  107: ******162259276829213363391578010288128 items
Square  108: ******324518553658426726783156020576256 items
Square  109: ******649037107316853453566312041152512 items
Square  110: *****1298074214633706907132624082305024 items
Square  111: *****2596148429267413814265248164610048 items
Square  112: *****5192296858534827628530496329220096 items
Square  113: ****10384593717069655257060992658440192 items
Square  114: ****20769187434139310514121985316880384 items
Square  115: ****41538374868278621028243970633760768 items
Square  116: ****83076749736557242056487941267521536 items
Square  117: ***166153499473114484112975882535043072 items
Square  118: ***332306998946228968225951765070086144 items
Square  119: ***664613997892457936451903530140172288 items
Square  120: **1329227995784915872903807060280344576 items
Square  121: **2658455991569831745807614120560689152 items
Square  122: **5316911983139663491615228241121378304 items
Square  123: *10633823966279326983230456482242756608 items
Square  124: *21267647932558653966460912964485513216 items
Square  125: *42535295865117307932921825928971026432 items
Square  126: *85070591730234615865843651857942052864 items
Square  127: 170141183460469231731687303715884105728 items
Square  128: 340282366920938463463374607431768211456 items
Enter exponent value for base-2 - Enter 0 to exit:
0

当迭代次数呈指数增长时,比如从 2​​^10 到 2^128,那么 String.format() 似乎有点慢。 所以,我用 StringBuilder 替换了 String.format 并且只取得了部分成功。

[sidebar]为简洁起见,我没有发布其余的程序代码,而且我的重点是显示的 padAgain(String,int) 方法。如果需要,将发布整个代码。[/sidebar]

**Initial code modified**
private static String padAgain(String result,int padNum)
    
        StringBuilder sb = new StringBuilder(result);
        for(int i = 1; i < padNum; i++)
        
              sb.insert(0, result).insert(sb.indexOf(result), " ").setLength(padNum - result.toCharArray().length);   
        
        sb.append(result);
        return sb.toString();
    

及其输出

Enter exponent value for base-2 - Enter 0 to exit: 
16
Square    1:  2 22 items
Square    2:  4 44 items
Square    3:  8 88 items
Square    4:  1616 items
Square    5:  3232 items
Square    6:  6464 items
Square    7:  1128 items
Square    8:  2256 items
Square    9:  5512 items
Square   10:  1024 items
Square   11:  2048 items
Square   12:  4096 items
Square   13:  8192 items
Square   14: 16384 items
Square   15: 32768 items
Square   16: 65536 items
Enter exponent value for base-2 - Enter 0 to exit: 
0

代码解释(我正在尝试做的事情):

变量'padNum'存储指数值的最大长度, 最大为 65536。长度 5 变量'result'是一个以字符串开头的数字表示 2 for 循环迭代直到最大。已达到长度 StringBuilder 对象在索引 0 处插入字符串值。在 这个,通过将“结果”作为子字符串传递来调用 indexOf(String) 本身并在位置 0 处插入空格,直到 max.length - 每个数字的长度 最后附加“结果”以弥补最大值。长度和 作为字符串值返回给调用对象

非常感谢论坛专家/成员可以帮助扩展/进一步修改/更正我的 StringBuilder 代码。

【问题讨论】:

问题是什么?您指的是哪个部分成功?它似乎符合您从示例输出中看到的预期效果? @Hiery,不。我的意图是留下号码。带有空格,并且仅适用于 5 位和 4 位数字。在样本输出中。对于 3,2 和个位数的编号,它会打印编号。而不是空格。 - javabegins293 【参考方案1】:

使用

String stars = "*".repeat(i);
sb.append(stars);

来自javadocs:

重复

public String repeat​(int count) 返回一个字符串,其值 是这个字符串重复count次的串联。

如果此字符串为空或计数为零,则空字符串为 返回。

参数: count - 重复的次数返回: 如果此字符串为空或计数为零,则由此字符串重复计数次或空字符串组成的字符串 抛出: IllegalArgumentException - 如果计数为负数。自从: 11

【讨论】:

【参考方案2】:

这可以通过 Java 11 显着简化,它在内部使用数组复制,字符串连接也应该在内部转换为 stringbuilder

public static String padNum(int number, String pad, int length)
    String numString = String.valueOf(number);
    int padLength = length - numString.length();
    if(padLength > 0)
        return pad.repeat(padLength) + numString;
    else
        return numString;

检查rest是否大于0,看是否需要pad,然后使用String.repeat生成大小合适的pad

字符串长度总是 >= padLength

【讨论】:

【参考方案3】:

您还可以使用Arraysfill() 方法实现更简单的操作。

StringBuilder sb = new StringBuilder();
char[] pad = new char[padnum - result.length()];
Arrays.fill(pad, '*');
return sb.append(pad).append(result).toString();

我们的时间真的很短,但这种方法比 for 循环快 25%。

【讨论】:

【参考方案4】:

Kostronor 的方法很棒,但只是为了一点不同的视角

public String pad(String value, int length) 
    return pad(value, length, " ");


public String pad(String value, int length, String with) 
    StringBuilder result = new StringBuilder(length);
    result.append(value);

    while (result.length() < length) 
        result.insert(0, with);
    

    return result.toString();

现在你可以用result.append(with); 反转这个想法来“填写”一个字符串

另一个想法

如果我们想减少内部 arraycopy 给我们带来任何额外开销的可能性(感谢 Kostonor 指出 ;)),我们可以改为:

public String fill(int length, String with) 
    StringBuilder sb = new StringBuilder(length);
    while (sb.length() < length) 
        sb.append(with);
    
    return sb.toString();


public String pad(String value, int length) 
    return pad(value, length, " ");


public String pad(String value, int length, String with) 
    StringBuilder result = new StringBuilder(length);
    // Pre-fill a String value
    result.append(fill(Math.max(0, length - value.length()), with));
    result.append(value);

    return result.toString();

好处是您可以获得一些可用于构建不同解决方案的额外方法。

例如,如果我们包括:

public String fill(String value, int length, String with) 

    StringBuilder result = new StringBuilder(length);
    result.append(value);
    result.append(fill(Math.max(0, length - value.length()), with));

    return result.toString();


然后执行

System.out.println("PAD: " + pad("Testing", 12, "*"));
System.out.println("PAD: " + pad("1", 12, "*"));
System.out.println("FILL: " + fill("1", 12, "*"));
System.out.println("FILL: " + fill("Testing", 12, "*"));

我们得到

PAD: *****Testing
PAD: ***********1
FILL: 1***********
FILL: Testing*****

感谢 Kostronor 是一项出色的运动,让我对自己的想法有了更多思考;)

【讨论】:

这也是个好主意!请记住,每次插入新空格时,Builder 都必须将整个字符串向前移动一个字符。在小范围内不会有明显的影响,它肯定更具可读性,但不是我最喜欢的解决方案;) 哦,同意,这只是对问题的另一种看法;)。看了StringBuilder 代码,insert 和append 几乎是一回事,除了insert 需要做一个arraycopy。在开始时设置 StringBuilder 的长度后,应确保不会浪费时间为新文本腾出更多空间,但 arraycopy 仍会增加​​(少量)开销跨度> 【参考方案5】:

简化一下怎么样?

padnum 是字符串的最大长度 result.length 是已经使用的长度

因此您可以通过从整体大小中减去对齐的字符串来计算需要多少个占位符来右对齐字符串。

StringBuilder sb = new StringBuilder();
int rest = padnum - result.length();
for(int i = 1; i < rest; i++)
    
         sb.append(" ");
    
sb.append(result);
return sb.toString();

这会计算需要添加多少个空格并将它们相加。 (使用StringBuilder,这个比较快) 最后,它会添加您的结果。

【讨论】:

@Kostronor,代码确实被简化了:)。从它的外观来看,我对多次插入调用等进行了不必要的复杂化。太感谢了! - javabegins293

以上是关于使用 StringBuilder 用空格或其他字符填充字符串的主要内容,如果未能解决你的问题,请参考以下文章

替换空格

python中字符串和列表只是汇总

仅用连字符替换单词之间的空格并删除所有其他空格[重复]

在Solr 7.x中,如何仅使用逗号而不是空格或其他特殊字符进行标记?

用StringBuilder(StringBuffer)#append替代字符串”+”会带来性能提升吗

用StringBuilder(StringBuffer)#append替代字符串”+”会带来性能提升吗