Java: วิธีแยกสตริงด้วยตัวคั่นโดยจำกัดจำนวนอักขระในสตริงได้อย่างไร

ฉันมีสถานการณ์ที่ฉันต้องแยกสตริง (ซึ่งมีค่าคั่นด้วยเครื่องหมายจุลภาค) เพื่อจำกัดจำนวนอักขระสูงสุดในสตริงในขณะที่ยังคงรักษารูปแบบที่คั่นด้วยเครื่องหมายจุลภาค

เช่น String str = "test,et,ste,ts,tst,est,ste,tstete,sts,tet,estst,tet"

สมมติว่าจำนวนอักขระสูงสุดในสตริงสามารถเป็น 10 ได้ ดังนั้นผลลัพธ์ของฉันควรเป็น:

test,et (7 chars)
ste,ts,tst (10 chars)
est,ste (7 chars)
tstete,sts (10 chars)
tet,estst (9 chars)
tet (3 chars)

โดยพื้นฐานแล้วเอาต์พุตจะถูกวนซ้ำและต่อท้ายส่วนคำสั่ง IN ในแบบสอบถาม แต่ส่วนคำสั่ง IN สามารถจัดการได้เท่านั้น (จำนวนตัวอักษรสูงสุด) ดังนั้นการแยกสตริง (โดยมีความหมายด้วยค่าที่คั่นด้วยเครื่องหมายจุลภาคเต็ม) ในกรณีที่ความยาวของสตริง เกินขีดจำกัด


person Devi    schedule 26.04.2019    source แหล่งที่มา
comment
ฉันจะแยกด้วยเครื่องหมายจุลภาค จากนั้นรวมสตริงอีกครั้งในลักษณะที่ไม่เกินขีดจำกัดขนาดของคุณ เพื่อประโยชน์เพิ่มเติม หากคุณกำลังมองหาความท้าทายจริงๆ คุณสามารถจัดเรียงสตริงใหม่ให้เหมาะสมที่สุดได้ (เช่น อาจไม่ใช่สตริงที่ต่อเนื่องกันในอินพุตต้นทาง)   -  person mprivat    schedule 27.04.2019
comment
นี่การบ้านเหรอ?   -  person luksch    schedule 27.04.2019
comment
@luksch ไม่นี่ไม่ใช่การบ้าน   -  person Devi    schedule 27.04.2019
comment
@mprivat ฉันเข้าใจคำตอบส่วนแรกของคุณ แต่ไม่ใช่ส่วนที่สอง ไม่จำเป็นต้องต่อเนื่องกัน แต่คุณมีโค้ดตัวอย่างเพื่อรวม string[] อีกครั้งโดยจำกัดขนาดอักขระหรือไม่   -  person Devi    schedule 27.04.2019


คำตอบ (3)


คุณสามารถทำสิ่งนี้ได้ (ดูความคิดเห็นสำหรับคำอธิบาย):

public static void main(String[] args) {
    String str = "test,et,ste,ts,tst,est,ste,tstete,sts,tet,estst,tet";

    // Split it first
    String words[] = str.split(",");

    // Use a buffer
    StringBuffer sb = new StringBuffer("");

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

    String delim = "";

    // Iterate through the words. 
    for(int i = 0; i< words.length; i++) {
        // You will add the comma so total length should be less 
        // than 10.
        if(sb.length() + words[i].length() < 10) {
            sb.append(delim);
            sb.append(words[i]);
            delim = ",";
        }
        else {
            delim = "";
            result.add(sb.toString());
            System.out.println(sb.toString());
            sb = new StringBuffer(words[i]);
            delim = ",";
        }
    }

    // Print to check the results
    for(String s: result) {
        System.out.println(s);
    }
}
person Pritam Banerjee    schedule 26.04.2019
comment
สิ่งนี้ไม่ได้ให้ผลลัพธ์ที่แน่นอนตามที่ฉันคาดหวัง ทั้งค่าที่พิมพ์ออกมามีค่าเท่ากัน มีวิธีใดบ้างที่เราสามารถทำได้โดยไม่ต้องสร้างวัตถุและใช้ฟังก์ชัน indexof และทำให้มันง่าย? - person Devi; 30.04.2019

งานนี้เป็นเรื่องยาก — นิพจน์แลมบ์ดาต่อไปนี้จะแก้ปัญหาได้

comma = false; // class boolean variable
last = 0;      // class int variable

Stream.of( str.split( "," ) ).collect(
  Collector.of( () -> new StringBuilder(),
    (buf, s) -> {
      if( buf.length() - last + s.length() < 10 ) {
        buf.append( comma ? "," : "" ).append( s );
        comma = true;
      }
      else {
        int len = buf.length();
        buf.append( " (" ).append( len - last ).append( " chars)\n" );
        last = buf.length();
        buf.append( s );
      }
    },
    (buf1, buf2) -> null,  // unused
    buf -> {
      int len = buf.length();
      return( buf.append( " (" ).append( len - last ).append( " chars)\n" ).toString() );
    } ) );

และไม่มี (… ตัวอักษร) - คำอธิบาย:

Stream.of( str.split( "," ) ).collect(
  Collector.of( () -> new StringBuilder(),
    (buf, s) -> {
      if( buf.length() - last + s.length() < 10 ) {
        buf.append( comma ? "," : "" ).append( s );
        comma = true;
      }
      else {
        buf.append( '\n' );
        last = buf.length();
        buf.append( s );
      }
    },
    (buf1, buf2) -> null,  // unused
    buf -> {
      return( buf.append( '\n' ).toString() );
    } ) );

ผลลัพธ์ที่ต้องการจะถูกส่งกลับเป็นสตริง...

person Kaplan    schedule 10.07.2019

ฉันจะทำสิ่งนี้:

  1. แยกสตริงอินพุตด้วยเครื่องหมายจุลภาค คุณจะได้รับอาร์เรย์กลับมาพร้อมกับสตริงเดี่ยว เช่น arr[]
  2. เตรียมใช้งานตัวแปรสตริงชั่วคราวเพื่อจัดเก็บเอาต์พุต เช่น out = ""
  3. วนซ้ำบนอาร์เรย์ เช่น for(int i = 0; i< arr.length; i++)
  4. ภายในลูป: หากความยาวของ out รวมกับความยาวของรายการอาเรย์ปัจจุบันน้อยกว่า 10 ให้เพิ่มรายการอาเรย์ปัจจุบันไปที่ out หรือพิมพ์ออกมา รีเซ็ตออกแล้วไปต่อ เช่น if (out.length + arr[i].length < 10) {out += ","+arr[i];} else {print out; out = "";}

บางทีฉันอาจลืมอะไรบางอย่าง... แต่คุณควรเข้าใจใช่ไหม?

person luksch    schedule 26.04.2019
comment
มีวิธีใดบ้างที่เราสามารถทำได้โดยไม่ต้องสร้างวัตถุใหม่และใช้ฟังก์ชัน indexof และทำให้มันง่าย? - person Devi; 30.04.2019
comment
โซลูชันที่แนะนำของฉันสร้างวัตถุตัวช่วยหนึ่งรายการซึ่งเป็นสตริง ไม่ได้ใช้ indexOf เพียงคุณสมบัติความยาวของสตริงซึ่งมีราคาไม่แพงในการคำนวณ แน่นอนคุณสามารถทำได้แทนที่จะสร้างสตริง out (โดยที่โซลูชันอื่นแนะนำให้ใช้ StringBuffer อย่างถูกต้อง) คุณสามารถใช้ตัวแปรนับได้ เพิ่มความยาวของแต่ละรายการอาร์เรย์ให้กับตัวแปรนับและเปรียบเทียบกับ 10 ถ้าใหญ่กว่าให้สร้างสตริง แต่นั่นไม่ได้หรูหรามากไปกว่านี้ฉันคิดว่า - person luksch; 30.04.2019