วิธีการแทรกตัวละครในสตริงที่ตำแหน่งที่แน่นอน?


155

ฉันได้รับในที่intมีค่า 6 หลัก ผมต้องการที่จะแสดงว่ามันเป็นStringมีจุดทศนิยม (.) ที่ 2 intหลักจากปลาย ฉันต้องการใช้floatแต่แนะนำให้ใช้Stringเพื่อให้ได้ผลลัพธ์การแสดงผลที่ดีขึ้น (แทนที่จะ1234.5เป็น1234.50) ดังนั้นฉันต้องการฟังก์ชั่นที่จะใช้intเป็นพารามิเตอร์และส่งกลับรูปแบบที่เหมาะสมStringด้วยทศนิยม 2 หลักจากจุดสิ้นสุด

พูด:

int j= 123456 
Integer.toString(j); 

//processing...

//output : 1234.56

1
String str = Integer.toString(j); //integer or string with white spaces<br/> str = new StringBuffer(str.trim()).insert(str.length()-2, ".").toString();
user881703

คำตอบ:


195
int j = 123456;
String x = Integer.toString(j);
x = x.substring(0, 4) + "." + x.substring(4, x.length());

6
เงื่อนไขไม่เปลี่ยนรูป ในขณะที่ใช้งานได้การใช้บางอย่างเช่น StringBuilder นั้นถูกต้องตามหลักจริยธรรมไม่พูดถึงจะทำให้โค้ดของคุณเร็วขึ้น
wheresmycookie

7
ลืม StringBuilder ด้วยการจัดรูปแบบเช่นนี้String.formatเป็นตัวเลือกที่ดีที่สุด
NobleUplift

33
ไม่มีลูปมันเป็นกรณีการต่อข้อมูลอย่างง่ายและคอมไพเลอร์ควรปรับให้เหมาะสมโดยใช้ตัวสร้างสตริงสำหรับการอ่านที่ฉันต้องการใช้ตัวดำเนินการ + ไม่จำเป็นต้องใช้ StringBuilder ในกรณีนี้อย่างชัดเจน การใช้โซลูชัน "StringBuilder" เพราะเร็วขึ้นไม่เคารพกฎการเพิ่มประสิทธิภาพ รหัสสำหรับการอ่าน ปรับให้เหมาะสมหลังจากการทำโปรไฟล์และเฉพาะที่จำเป็นเท่านั้น en.wikipedia.org/wiki/Program_optimization#Quotes
Remi Morin

17
คุณไม่จำเป็นต้องมี x.length () ในการเรียกสายย่อยที่สอง
crazyGuy

1
วิธีนี้จะล้มเหลวเมื่อตัวเลขเป็นจำนวนหลักที่แตกต่างกัน สำหรับ 12345 จะส่งออก 1234.5 และสำหรับ 1234567 จะเป็น 1234.567 หากคุณต้องการให้ตัวเลข 2 หลักสุดท้ายอยู่หลังจุดทศนิยมให้ตรวจสอบว่าตัวเลขมีอย่างน้อย 3 หลักจากนั้นทำx = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
Teodor Marinescu

210

ตามที่ระบุไว้ในการแสดงความคิดเห็นเป็นStringBuilderอาจจะเป็นการใช้งานได้เร็วขึ้นกว่าการใช้StringBuffer ตามที่กล่าวไว้ในเอกสาร Java:

คลาสนี้ให้ API ที่เข้ากันได้กับ StringBuffer แต่ไม่มีการรับประกันการซิงโครไนซ์ คลาสนี้ถูกออกแบบมาเพื่อใช้แทนการแทนที่สำหรับ StringBuffer ในสถานที่ที่มีการใช้บัฟเฟอร์สตริงโดยเธรดเดียว (โดยทั่วไปเป็นกรณี) หากเป็นไปได้ขอแนะนำให้ใช้คลาสนี้ในการกำหนดค่าตามความชอบกับ StringBuffer เนื่องจากจะเร็วกว่าในการนำไปใช้งานส่วนใหญ่

การใช้งาน:

String str = Integer.toString(j);
str = new StringBuilder(str).insert(str.length()-2, ".").toString();

หรือถ้าคุณต้องการซิงโครไนซ์ให้ใช้StringBufferด้วยการใช้ที่คล้ายกัน:

String str = Integer.toString(j);
str = new StringBuffer(str).insert(str.length()-2, ".").toString();

1
โซลูชันนี้ใช้ได้กับสตริงใด ๆ > = 4 ตัวอักษร: สตริง "111" ให้ฉัน ".111" และสิ่งใดก็ตามที่น้อยกว่าผลลัพธ์จะเป็น a java.lang.StringIndexOutOfBoundsException(พยายามเข้าถึงการอ้างอิงที่ไม่มีอยู่)
sotrh

17
int yourInteger = 123450;
String s = String.format("%6.2f", yourInteger / 100.0);
System.out.println(s);

ผมขอแนะนำให้ใช้java.math.BigDecimalกับการใช้doubleอาจทำให้เกิดการปัดเศษข้อผิดพลาด หากความเร็วมีค่ามากกว่าความแม่นยำdoubleจะดีกว่า
sotrh

5

ในกรณีการใช้งานส่วนใหญ่การใช้StringBuilder(ตามคำตอบแล้ว) เป็นวิธีที่ดีในการทำเช่นนี้ อย่างไรก็ตามหากประสิทธิภาพมีความสำคัญนี่อาจเป็นทางเลือกที่ดี

/**
 * Insert the 'insert' String at the index 'position' into the 'target' String.
 * 
 * ````
 * insertAt("AC", 0, "") -> "AC"
 * insertAt("AC", 1, "xxx") -> "AxxxC"
 * insertAt("AB", 2, "C") -> "ABC
 * ````
 */
public static String insertAt(final String target, final int position, final String insert) {
    final int targetLen = target.length();
    if (position < 0 || position > targetLen) {
        throw new IllegalArgumentException("position=" + position);
    }
    if (insert.isEmpty()) {
        return target;
    }
    if (position == 0) {
        return insert.concat(target);
    } else if (position == targetLen) {
        return target.concat(insert);
    }
    final int insertLen = insert.length();
    final char[] buffer = new char[targetLen + insertLen];
    target.getChars(0, position, buffer, 0);
    insert.getChars(0, insertLen, buffer, position);
    target.getChars(position, targetLen, buffer, position + insertLen);
    return new String(buffer);
}

4

การใช้ ApacheCommons3 StringUtils คุณสามารถทำได้

int j = 123456;
String s = Integer.toString(j);
int pos = s.length()-2;

s = StringUtils.overlay(s,".", pos, pos);

โดยทั่วไปแล้วการต่อข้อมูลย่อยจะสั้นกว่า แต่สั้นกว่าถ้าคุณไม่สนใจใช้ห้องสมุด


2

คุณสามารถใช้

System.out.printf("%4.2f%n", ((float)12345)/100));

ตามความคิดเห็น 12345 / 100.0 จะดีกว่าเช่นเดียวกับการใช้สองครั้งแทนการลอย


2
doubleอาจเป็นทางเลือกที่ดีกว่า ทศนิยมนั้นถูกต้องเพียง 6 หลักเท่านั้น
Peter Lawrey

1
ใช่อีกตัวอย่างหนึ่งที่ใครบางคนตอบก็คือใช้ 12345 / 100.0 ซึ่งฉลาดกว่า (แม้ว่าผลลัพธ์จะออกมาเหมือนกัน)
Joseph Ottinger

Nitpicking: ฉันคิดว่าสิ่งนี้จะไม่ให้ผลลัพธ์ที่ถูกต้องเพราะ 12345/100 = 123 เป็นจำนวนเต็มและใช้เพียง 123.00 หลังจากนั้น ((ลอย) 12345/100) จะใช้งานได้
rurouni

เฮ้จุดดี - ฉันไม่ได้คำนึงถึงลำดับความสำคัญเพราะส่วนใหญ่เป็นครั้งแรกที่เขาวิ่งมันจะให้ผลลัพธ์ที่ถูกตัดทอน จะแก้ไขโพสต์ (ซึ่งเคยบอกว่า 12345/100 แล้วส่งผลลัพธ์แทนการเพิ่มค่าก่อน)
Joseph Ottinger

0

หากคุณกำลังใช้ระบบที่มีราคาแพงลอยตัว (เช่นไม่มี FPU) หรือไม่ได้รับอนุญาต (เช่นในบัญชี) คุณสามารถใช้สิ่งนี้:

    for (int i = 1; i < 100000; i *= 2) {
        String s = "00" + i;
        System.out.println(s.substring(Math.min(2, s.length() - 2), s.length() - 2) + "." + s.substring(s.length() - 2));
    }

มิฉะนั้น DecimalFormat จะเป็นทางออกที่ดีกว่า (ตัวแปร StringBuilder ด้านบนจะไม่ทำงานกับตัวเลขขนาดเล็ก (<100)


2
ในกรณีของการบัญชีคุณจะดีขึ้นด้วย BigDecimal
Joseph Ottinger

@Joseph: คุณพูดถูก ผมไม่ได้อยู่ในบัญชีและผมส่วนใหญ่ใช้ ints เป็นตัวแทน fixedpoint เพื่อเหตุผลด้านประสิทธิภาพ (ใน java ฝังตัว) ดังนั้น BigDecimal ไม่ได้เป็นตัวเลือกของฉัน ;-)
Rurouni

0

ฉันคิดว่าวิธีที่ง่ายและสง่างามกว่าในการแทรกสตริงในตำแหน่งที่แน่นอนน่าจะเป็นหนึ่งซับ:

target.replaceAll("^(.{" + position + "})", "$1" + insert);

ตัวอย่างเช่นเมื่อต้องการแทรกการหายไป:ใน String เวลา:

"-0300".replaceAll("^(.{3})", "$1:");

มันทำอะไรตรงกับpositionตัวละครจากจุดเริ่มต้นของสตริงกลุ่มที่และแทนที่กลุ่มด้วยตัวเอง ( $1) ตามด้วยinsertสตริง คำนึงถึง replaceAll แม้ว่าจะมีเหตุการณ์หนึ่งเกิดขึ้นเสมอเพราะพารามิเตอร์แรกจะต้องเป็น regex

แน่นอนว่ามันไม่ได้มีประสิทธิภาพเช่นเดียวกับโซลูชัน StringBuilder แต่ฉันเชื่อว่ารวบรัดและความสง่างามเป็นวิธีที่ง่ายและง่ายต่อการอ่านหนึ่งซับ (เมื่อเทียบกับวิธีการขนาดใหญ่) ก็เพียงพอแล้วที่จะทำให้มันเป็นโซลูชั่นที่ต้องการ - กรณีการใช้ที่สำคัญ

หมายเหตุฉันแก้ไขปัญหาทั่วไปในชื่อเรื่องด้วยเหตุผลด้านเอกสารแน่นอนถ้าคุณจัดการกับเลขทศนิยมคุณควรใช้วิธีแก้ปัญหาเฉพาะโดเมนที่เสนอมาแล้ว


0

String.format ("% 0d.% 02d", d / 100, d% 100);


สำหรับผู้ที่ลงคะแนนในสิ่งนี้: โปรดอ่านสิ่งที่ OP อธิบายในรายละเอียด นี่เป็นคำตอบที่ถูกต้องสำหรับปัญหา: ไม่มีเลขทศนิยม วางจุดทศนิยมในตำแหน่งที่ถูกต้อง หากต้องการปัญญาstackoverflow.com/a/5884413/972128ให้คำตอบที่คล้ายกัน แต่ใช้จุดลอยตัว (ไม่ต้องการ) และมี 17 upvotes ในเวลานี้
kkurian

0

สำหรับ Kotlin dudes;) จากคำตอบที่ยอมรับ (@ MikeThomsen's)

fun String.insert(index: Int, string: String): String {
    return this.substring(0, index) + string + this.substring(index, this.length)
}

ทดสอบ✅

"ThisTest".insert(4, "Is").should.equal("ThisIsTest")

-2
  public static void main(String[] args) {
    char ch='m';
    String str="Hello",k=String.valueOf(ch),b,c;

    System.out.println(str);

    int index=3;
    b=str.substring(0,index-1 );
    c=str.substring(index-1,str.length());
    str=b+k+c;
}

-2
// Create given String and make with size 30
String str = "Hello How Are You";

// Creating StringBuffer Object for right padding
StringBuffer stringBufferRightPad = new StringBuffer(str);
while (stringBufferRightPad.length() < 30) {
    stringBufferRightPad.insert(stringBufferRightPad.length(), "*");
}

System.out.println("after Left padding : " + stringBufferRightPad);
System.out.println("after Left padding : " + stringBufferRightPad.toString());

// Creating StringBuffer Object for right padding
StringBuffer stringBufferLeftPad = new StringBuffer(str);
while (stringBufferLeftPad.length() < 30) {
    stringBufferLeftPad.insert(0, "*");
}
System.out.println("after Left padding : " + stringBufferLeftPad);
System.out.println("after Left padding : " + stringBufferLeftPad.toString());

2
ยินดีต้อนรับสู่ Stack Overflow! โดยทั่วไปแล้วคำตอบมีประโยชน์มากขึ้นหากพวกเขามีคำอธิบายว่ารหัสนี้มีจุดประสงค์เพื่ออะไรและเหตุใดจึงแก้ปัญหาได้โดยไม่ต้องแนะนำผู้อื่น ขอบคุณสำหรับการปรับปรุงค่าอ้างอิงของคำตอบและทำให้เข้าใจได้ง่ายขึ้น!
ทิม Diekmann

กรุณาอย่าใช้ StringBuffer เป็นมันถูกแทนที่ด้วย StringBuilder ในปี 2004
ปีเตอร์ Lawrey

-2

ลองสิ่งนี้:

public String ConvertMessage(String content_sendout){

        //use unicode (004E00650077) need to change to hex (&#x004E&#x;0065&#x;0077;) first ;
        String resultcontent_sendout = "";
        int i = 4;
        int lengthwelcomemsg = content_sendout.length()/i;
        for(int nadd=0;nadd<lengthwelcomemsg;nadd++){
            if(nadd == 0){
                resultcontent_sendout = "&#x"+content_sendout.substring(nadd*i, (nadd*i)+i) + ";&#x";
            }else if(nadd == lengthwelcomemsg-1){
                resultcontent_sendout += content_sendout.substring(nadd*i, (nadd*i)+i) + ";";
            }else{
                resultcontent_sendout += content_sendout.substring(nadd*i, (nadd*i)+i) + ";&#x";
            }
        }
        return resultcontent_sendout;
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.