Tạo một chuỗi có n ký tự


144

Có cách nào trong java để tạo một chuỗi với một số ký tự được chỉ định không? Trong trường hợp của tôi, tôi sẽ cần tạo một chuỗi có 10 khoảng trắng. Mã hiện tại của tôi là:

StringBuffer outputBuffer = new StringBuffer(length);
for (int i = 0; i < length; i++){
   outputBuffer.append(" ");
}
return outputBuffer.toString();

Có cách nào tốt hơn để hoàn thành điều tương tự. Đặc biệt tôi muốn một cái gì đó nhanh chóng (về mặt thực thi).


1
Nếu bạn thấy mình làm việc đó rất nhiều, chỉ cần viết một hàm: String characterRepeat (Char c, int length) {...} làm những gì bạn làm ở đó cho bất kỳ ký tự và độ dài nào. Sau đó, chỉ cần gọi nó khi bạn cần nó.
Austin Fitzpatrick

12
bạn muốn sử dụng StringBuilder thay vì StringBuffer

Thêm vào kích thước của bộ đệm, dễ dàng tính toán một điều kiện thuận lợi cho mọi thứ trong bộ nhớ quản lý!. StringBuilder outputBuffer = new StringBuilder (lặp lại * base.length ());
Victor


Nếu bạn muốn nối thêm một khoảng trắng, append(' ')thay vào đó hãy sử dụng ... nó liên quan đến việc tính toán ít hơn một chút ...
Erk

Câu trả lời:


36

Vòng lặp for sẽ được tối ưu hóa bởi trình biên dịch. Trong những trường hợp như của bạn, bạn không cần phải quan tâm đến việc tối ưu hóa một mình. Tin tưởng vào trình biên dịch.

BTW, nếu có một cách để tạo một chuỗi có n ký tự khoảng trắng, thì nó được mã hóa giống như cách bạn vừa làm.


1
ngay cả khi điều này không được tối ưu hóa - tần suất này được tạo trong chương trình của bạn - nếu thường lưu trong một biến tĩnh hoặc bộ đệm khác
mmmmmm

btw Array.fill () chỉ vòng lặp qua mảng. / tôi cần dứt khoát nhiều điểm hơn để bình luận về bài đăng của người khác :)
kalkin

@Mark Chiều dài là biến, vì vậy có vẻ ngớ ngẩn khi lưu nó. Tôi sẽ làm gì, có một static Dictionary<int, String>?
C. Ross

1
Lưu trữ lâu nhất bạn sẽ muốn chuỗi, sau đó sử dụng một cái gì đó như thế này: " ".substring(0, 10);
mjaggard

169

Có thể là mã ngắn nhất sử dụng StringAPI, độc quyền:

String space10 = new String(new char[10]).replace('\0', ' ');

System.out.println("[" + space10 + "]");
// prints "[          ]"

Như một phương pháp, không cần khởi tạo trực tiếp char:

import java.nio.CharBuffer;

/**
 * Creates a string of spaces that is 'spaces' spaces long.
 *
 * @param spaces The number of spaces to add to the string.
 */
public String spaces( int spaces ) {
  return CharBuffer.allocate( spaces ).toString().replace( '\0', ' ' );
}

Gọi bằng cách sử dụng:

System.out.printf( "[%s]%n", spaces( 10 ) );

4
Mặc dù tôi thích một lớp lót, tôi nghĩ giải pháp của FrustratedWithFormsDes là tốt hơn khi thực hiện vì nó tránh kiểm tra từng cái cho 0 và chỉ cần gán không gian.
Bouncner

1
Đã thử nghiệm, tốc độ này luôn nhanh hơn vòng lặp, khá nhanh 50000-100000 nano giây, có thể khá đáng kể (0,1 mili giây) vòng lặp sẽ nhanh hơn khi số lần lặp tăng lên mặc dù tổng thời gian vẫn còn cao. Điều này đúng khi tạo các kích thước khác nhau của chuỗi không gian.
kmecpp

thump lên cho giải pháp tốt đẹp khá, tôi đã sử dụng nó trong câu trả lời của tôi ở đây stackoverflow.com/questions/852665/...
maytham-ɯɐɥʇʎɐɯ

66

Hmm bây giờ tôi nghĩ về nó, có thể Arrays.fill:

char[] charArray = new char[length];
Arrays.fill(charArray, ' ');
String str = new String(charArray);

Tất nhiên, tôi giả sử rằng fillphương thức này thực hiện tương tự như mã của bạn, vì vậy nó có thể sẽ thực hiện tương tự, nhưng ít nhất đây là ít dòng hơn.


2
Sau khi kiểm tra nguồn, có vẻ như thực tế điều này thực hiện chính xác những gì OP đã đăng: dòng 806 của docjar.com/html/api/java/util/Arrays.java.html
Pops

2
@Lord Torgamus Câu hỏi của OP đã được chỉnh sửa chưa? Bởi vì trong phiên bản tôi thấy, anh ta đang lặp lại trên StringBuffer.append () và phiên bản của Frustrated đang thực hiện điền (tất nhiên các vòng lặp thực hiện các phép gán char cho mảng). Không giống chút nào.
CPerkins

@CPerkins, đủ công bằng, tôi đã không rõ ràng. Quan điểm của tôi là cả hai đều thực hiện chèn từng ký tự bên trong một vòng lặp for.
Pops

1
@ Lord Torgamus - Đồng ý về điều đó. đáng tiếc jvm không thể làm một bộ nhớ. Giá chúng tôi phải trả cho các nhân vật rộng.
CPerkins

2
@ Xin lưu ý rằng nếu Arrays.fill()hàm được sử dụng nhất quán để thực hiện công việc này trên mã của bạn mã thư viện (tiêu chuẩn và bên ngoài), thì nó sẽ là một ứng cử viên tốt cho việc biên dịch Hotspot và có nhiều khả năng tìm thấy bộ đệm CPU của bạn hơn. Các JVM tương lai có thể gán nó như là một hàm nội tại . Việc tự mình loại bỏ bạn khỏi tất cả sự tốt đẹp về hiệu suất này ...
SusanW

65

Tôi khuyên bạn không nên viết vòng lặp bằng tay. Bạn sẽ làm điều đó nhiều lần trong suốt sự nghiệp lập trình của bạn. Những người đọc mã của bạn - bao gồm bạn - luôn phải đầu tư thời gian, ngay cả khi chỉ mất vài giây, để tiêu hóa ý nghĩa của vòng lặp.

Thay vào đó, hãy sử dụng lại một trong những thư viện có sẵn cung cấp mã giống như StringUtils.repeattừ Apache Commons Lang :

StringUtils.repeat(' ', length);

Bằng cách đó, bạn cũng không phải bận tâm về hiệu suất, do đó tất cả các chi tiết cơ bản về StringBuilder, tối ưu hóa Trình biên dịch, v.v. đều bị ẩn. Nếu chức năng bật ra chậm thì đó sẽ là một lỗi của thư viện.

Với Java 11, nó trở nên dễ dàng hơn nữa:

" ".repeat(length);

5
Mặt khác, nếu StringUtils chưa được sử dụng trong dự án, việc thêm một phụ thuộc khác cho một nhiệm vụ đơn giản như vậy có thể là quá mức cần thiết.
Erich Kitzmueller

1
nếu nó bật ra chậm, bạn cũng có thể gửi bản sửa lỗi cho hàm.
sẽ

26

Trong Java 8, bạn có thể sử dụng String.join:

String.join("", Collections.nCopies(n, s));

13

Nếu bạn chỉ muốn khoảng trắng, thì làm thế nào:

String spaces = (n==0)?"":String.format("%"+n+"s", "");

sẽ dẫn đến không gian abs (n);


6
Làm thế nào là tốc độ mặc dù? Tôi ở định dạng hiển thị tương đối chậm. Nó phải phân tích chuỗi trước khi có thể tạo ra chuỗi.
C. Ross

11

kể từ Java 11 :

" ".repeat(10);

kể từ Java 8 :

generate(() -> " ").limit(10).collect(joining());

Ở đâu:

import static java.util.stream.Collectors.joining;
import static java.util.stream.Stream.generate;

9

Vì Java 11, bạn chỉ cần sử dụng String.repeat(count)để giải quyết vấn đề của mình.

Trả về một chuỗi có giá trị là nối của chuỗi này lặp lại nhiều countlần.

Nếu chuỗi này trống hoặc countbằng 0 thì chuỗi trống được trả về.

Vì vậy, thay vì một vòng lặp, mã của bạn sẽ trông như thế này:

" ".repeat(length);

8

Tôi nghĩ rằng đây là mã ít hơn nó có thể, nó sử dụng lớp Guava Joiner:

Tham gia .on (""). Tham gia ( Bộ sưu tập.nCopies (10, ""));


Dòng mã ngắn nhất nhưng thêm một thư viện lớn chỉ cho nhiệm vụ đơn giản đó sẽ không có ý nghĩa. Tôi có thể tự tạo một JAR nhỏ hơn bằng một phương thức duy nhất pubic String n(int n) { ... }cho phép mã "ít" hơn: n(10)nhưng một lần nữa, không có ý nghĩa gì.
isapir

@isapir Đây là một câu trả lời tuyệt vời cho những người đã sử dụng Guava
vào

1
@nasch Quả ổi không phải là một phần của câu hỏi. Nhưng dù sao, vào năm 2018, thực sự không có lý do gì để sử dụng Guava's Joiner khi bạn có thể sử dụng String.join () đã được thêm vào Java 8. Xem stackoverflow.com/a/43011939/968244
isapir

@isapir Không, ổi là một câu trả lời. Câu trả lời trên StackOverflow có đối tượng rộng hơn so với chỉ người hỏi câu hỏi, vì vậy thật tốt nếu một số câu trả lời không phù hợp nhất với người hỏi. Và nhận xét về String.join () là một điều tuyệt vời mặc dù tôi không chắc liệu nó có sẵn trên tất cả các phiên bản Android hay không, đây là một cách sử dụng Java nổi bật.
mũi

7

Bạn có thể sử dụng String.formatchức năng tiêu chuẩn để tạo N khoảng trắng. Ví dụ:

String.format("%5c", ' ');

Tạo một chuỗi có 5 khoảng trắng.

hoặc là

int count = 15;
String fifteenSpacebars = String.format("%" + count + "c", ' ');

Làm cho một chuỗi gồm 15 tàu vũ trụ.

Nếu bạn muốn một biểu tượng khác lặp lại, bạn phải thay thế khoảng trắng bằng biểu tượng bạn muốn:

int count = 7;
char mySymbol = '#';
System.out.println(String.format("%" + count + "c", ' ').replaceAll("\\ ", "\\" + mySymbol));

Đầu ra:

#######

6

Đóng góp của tôi dựa trên thuật toán cho lũy thừa nhanh.

/**
 * Repeats the given {@link String} n times.
 * 
 * @param str
 *            the {@link String} to repeat.
 * @param n
 *            the repetition count.
 * @throws IllegalArgumentException
 *             when the given repetition count is smaller than zero.
 * @return the given {@link String} repeated n times.
 */
public static String repeat(String str, int n) {
    if (n < 0)
        throw new IllegalArgumentException(
                "the given repetition count is smaller than zero!");
    else if (n == 0)
        return "";
    else if (n == 1)
        return str;
    else if (n % 2 == 0) {
        String s = repeat(str, n / 2);
        return s.concat(s);
    } else
        return str.concat(repeat(str, n - 1));
}

Tôi đã thử nghiệm thuật toán theo hai cách tiếp cận khác:

  • Thường xuyên cho vòng lặp sử dụng String.concat()để nối chuỗi
  • Thường xuyên cho vòng lặp sử dụng một StringBuilder

Mã kiểm tra (nối bằng cách sử dụng vòng lặp for và String.concat()trở nên chậm cho lớn n, vì vậy tôi đã bỏ nó sau lần lặp thứ 5).

/**
 * Test the string concatenation operation.
 * 
 * @param args
 */
public static void main(String[] args) {
    long startTime;
    String str = " ";

    int n = 1;
    for (int j = 0; j < 9; ++j) {
        n *= 10;
        System.out.format("Performing test with n=%d\n", n);

        startTime = System.currentTimeMillis();
        StringUtil.repeat(str, n);
        System.out
                .format("\tStringUtil.repeat() concatenation performed in    %d milliseconds\n",
                        System.currentTimeMillis() - startTime);

        if (j <5) {
            startTime = System.currentTimeMillis();
            String string = "";
            for (int i = 0; i < n; ++i)
                string = string.concat(str);
            System.out
                    .format("\tString.concat() concatenation performed in        %d milliseconds\n",
                            System.currentTimeMillis() - startTime);
        } else
            System.out
                    .format("\tString.concat() concatenation performed in        x milliseconds\n");
        startTime = System.currentTimeMillis();
        StringBuilder b = new StringBuilder();
        for (int i = 0; i < n; ++i)
            b.append(str);
        b.toString();
        System.out
                .format("\tStringBuilder.append() concatenation performed in %d milliseconds\n",
                        System.currentTimeMillis() - startTime);
    }
}

Các kết quả:

Performing test with n=10
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        0 milliseconds
    StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=100
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        1 milliseconds
    StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=1000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        1 milliseconds
    StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=10000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        43 milliseconds
    StringBuilder.append() concatenation performed in 5 milliseconds
Performing test with n=100000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        1579 milliseconds
    StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=1000000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 10 milliseconds
Performing test with n=10000000
    StringUtil.repeat() concatenation performed in    7 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 112 milliseconds
Performing test with n=100000000
    StringUtil.repeat() concatenation performed in    80 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 1107 milliseconds
Performing test with n=1000000000
    StringUtil.repeat() concatenation performed in    1372 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 12125 milliseconds

Phần kết luận:

  • Đối với lớn n- sử dụng phương pháp đệ quy
  • Đối nvới vòng lặp nhỏ - for có đủ tốc độ

4
Đây là một thực hiện thú vị. Thật không may, trái với kết luận của bạn, nó rất không hiệu quả đối với n lớn. Tôi nghi ngờ điều này là do nhiều phân bổ bộ nhớ đang diễn ra mỗi khi bạn nối chuỗi. Hãy thử viết nó như một trình bao bọc xung quanh một phương thức đệ quy lấy StringBuilder thay vì String. Tôi cá là bạn sẽ thấy kết quả sẽ tốt hơn nhiều.
Klitos Kyriacou

3
Có rất nhiều biện pháp phòng ngừa bạn cần thực hiện khi điểm chuẩn vi mô như thế này và tôi không nghĩ rằng bạn đang thực hiện bất kỳ biện pháp nào trong số đó! Các câu hỏi về hiệu năng vượt trội xung quanh mã này có thể dễ dàng là liệu nó có được biên dịch Hotspot hay không, nó tạo ra bao nhiêu rác, v.v. Tôi cá rằng tất cả các ifcâu lệnh đó sẽ làm xáo trộn dự đoán nhánh của CPU. Điều này thực sự nên được làm lại bằng cách sử dụng JMH ( openjdk.java.net/projects/code-tools/jmh ), nếu không thì hơi vô nghĩa.
SusanW

Lưu ý rằng việc triển khai này có độ phức tạp O (n * log n), trong khi StringBuilder là O (n) :)
Leo Leontev


4

Xem xét chúng tôi có:

String c = "c"; // character to repeat, for empty it would be " ";
int n = 4; // number of times to repeat
String EMPTY_STRING = ""; // empty string (can be put in utility class)

Java 8 (Sử dụng luồng)

String resultOne = IntStream.range(0,n)
   .mapToObj(i->c).collect(Collectors.joining(EMPTY_STRING)); // cccc

Java 8 (Sử dụng nCopies)

String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc

1
Collectors.joining(EMPTY_STRING)tương đương vớiCollectors.joining()
PPartisan

2

RandomStringUtils có một điều khoản để tạo một chuỗi từ kích thước đầu vào đã cho. Không thể nhận xét về tốc độ, nhưng nó là một lót.

RandomStringUtils.random(5,"\t");

tạo ra một đầu ra

\ t \ t \ t \ t \ t

tốt hơn nếu bạn không muốn thấy \ 0 trong mã của mình.



1

Trong hầu hết các trường hợp, bạn chỉ cần Chuỗi tối đa độ dài xác nhận, giả sử 100 khoảng trắng. Bạn có thể chuẩn bị một chuỗi Chuỗi trong đó số chỉ mục bằng với kích thước của chuỗi chứa đầy khoảng trắng và tra cứu chuỗi, nếu độ dài yêu cầu nằm trong giới hạn hoặc tạo theo yêu cầu nếu nó nằm ngoài ranh giới.



0

Chỉ cần thay thế StringBuffer của bạn bằng StringBuilder . Khó mà đánh bại được.

Nếu độ dài của bạn là một con số lớn, bạn có thể thực hiện một số tự bổ sung hiệu quả hơn (nhưng vụng về hơn), nhân đôi độ dài trong mỗi lần lặp:

 public static String dummyString(char c, int len) {
  if( len < 1 ) return "";
  StringBuilder sb = new StringBuilder(len).append(c);
  int remnant = len - sb.length();
  while(remnant  > 0) {
   if( remnant  >= sb.length() ) sb.append(sb);
   else sb.append(sb.subSequence(0, remnant));
   remnant  = len - sb.length();
  }
  return sb.toString();
 }

Ngoài ra, bạn có thể thử Arrays.fill()aproach ( câu trả lời của FrustratedWithFormsDesigner ).


Bạn có thể đặt tên cho một số biến nhiều hơn một ký tự không?
C. Ross

0

Bạn có thể thay thế StringBufferbằng StringBuilder(cái sau không được đồng bộ hóa, có thể nhanh hơn trong một ứng dụng chủ đề)

Và bạn có thể tạo StringBuildercá thể một lần, thay vì tạo nó mỗi lần bạn cần.

Một cái gì đó như thế này:

class BuildString {
     private final StringBuilder builder = new StringBuilder();
     public String stringOf( char c , int times ) {

         for( int i = 0 ; i < times ; i++  ) {
             builder.append( c );
         }
         String result = builder.toString();
         builder.delete( 0 , builder.length() -1 );
         return result;
      }

  }

Và sử dụng nó như thế này:

 BuildString createA = new BuildString();
 String empty = createA.stringOf( ' ', 10 );

Nếu bạn giữ createAbiến làm ví dụ của mình, bạn có thể tiết kiệm thời gian tạo phiên bản.

Đây không phải là chủ đề an toàn, nếu bạn có nhiều luồng, mỗi luồng nên có bản sao riêng.


0

Để có hiệu suất tốt, hãy kết hợp các câu trả lời từ aznilamir và từ FrustratedWithFormsDesigner

private static final String BLANKS = "                       ";
private static String getBlankLine( int length )
{
    if( length <= BLANKS.length() )
    {
        return BLANKS.substring( 0, length );
    }
    else
    {
        char[] array = new char[ length ];
        Arrays.fill( array, ' ' );
        return new String( array );
    }
}

Điều chỉnh kích thước BLANKStùy thuộc vào yêu cầu của bạn. BLANKSChuỗi cụ thể của tôi có độ dài khoảng 200 ký tự.


0

Có một phương pháp như thế này. Điều này nối thêm các không gian cần thiết ở cuối phần đã cho Stringđể tạo một khoảng cho Stringchiều dài cụ thể.

public static String fillSpaces (String str) {

    // the spaces string should contain spaces exceeding the max needed
    String spaces = "                                                   ";
    return str + spaces.substring(str.length());
}

0

Muốn Chuỗi có kích thước cố định, do đó, bạn có thể đệm hoặc cắt bớt, để lập bảng dữ liệu ...

class Playground {
    private static String fixStrSize(String s, int n) {
        return String.format("%-" + n + "s", String.format("%." + n +"s", s));
    }

    public static void main(String[ ] args) {
        System.out.println("|"+fixStrSize("Hell",8)+"|");
        System.out.println("|"+fixStrSize("Hells Bells Java Smells",8)+"|");
    }
}

|Hell    |
|Hells Be|

Tham khảo tuyệt vời ở đây .


0

Điều này làm việc cho tôi mà không cần sử dụng bất kỳ thư viện bên ngoài nào trong Java 8

String sampleText = "test"
int n = 3;
String output = String.join("", Collections.nCopies(n, sampleText));
System.out.println(output);

Và đầu ra là

testtesttest

0

int c = 10; Không gian chuỗi = String.format ("%" + c + "c", ''); Điều này sẽ giải quyết vấn đề của bạn.


-1

Một phương pháp đơn giản như dưới đây cũng có thể được sử dụng

public static String padString(String str, int leng,char chr) {
        for (int i = str.length(); i <= leng; i++)
            str += chr;
        return str;
    }

Đây là chậm hơn.
SLaks

Bạn có thể sử dụng StringBuffer thay vì nối chuỗi, trong trường hợp chuỗi bạn đang xử lý có kích thước lớn. Điều đó sẽ tác động đến tốc độ đáng kể
Yashpal Singla

-2

Còn cái này thì sao?

public String fillSpaces(int len) {
    /* the spaces string should contain spaces exceeding the max needed */  
    String spaces = "                                                   ";
    return spaces.substring(0,len);
}

EDIT: Tôi đã viết một mã đơn giản để kiểm tra khái niệm và ở đây những gì tôi tìm thấy.

Phương pháp 1: thêm không gian đơn trong một vòng lặp:

  public String execLoopSingleSpace(int len){
    StringBuilder sb = new StringBuilder();

    for(int i=0; i < len; i++) {
        sb.append(' ');
    }

    return sb.toString();
  }

Phương pháp 2: nối thêm 100 khoảng trắng và vòng lặp, sau đó chuỗi con:

  public String execLoopHundredSpaces(int len){
    StringBuilder sb = new StringBuilder("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ");

    for (int i=0; i < len/100 ; i++) {
        sb.append("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ");
    }

    return sb.toString().substring(0,len);
  }

Kết quả tôi nhận được tạo 12.345.678 chỗ trống:

C:\docs\Projects> java FillSpace 12345678
method 1: append single spaces for 12345678 times. Time taken is **234ms**. Length of String is 12345678
method 2: append 100 spaces for 123456 times. Time taken is **141ms**. Length of String is 12345678
Process java exited with code 0

và cho 10.000.000 không gian:

C:\docs\Projects> java FillSpace 10000000
method 1: append single spaces for 10000000 times. Time taken is **157ms**. Length of String is 10000000
method 2: append 100 spaces for 100000 times. Time taken is **109ms**. Length of String is 10000000
Process java exited with code 0

kết hợp phân bổ trực tiếp và lặp lại luôn mất ít thời gian hơn, trung bình ít hơn 60ms khi tạo không gian lớn. Đối với kích thước nhỏ hơn, cả hai kết quả là không đáng kể.

Nhưng hãy tiếp tục bình luận :-)


3
@ aznilamir: Hừm, bạn sẽ làm thế nào cho không gian 10k?
Jayan

Ý tưởng là kết hợp vòng lặp và phân bổ trực tiếp 100 không gian. Đây là đoạn mã:
aznilamir

Tại sao bạn sử dụng nhiều phụ lục để thêm 100 ký tự? Tại sao không phải là một char 100 append?
nycynik

-3

Tôi biết không có phương pháp tích hợp nào cho những gì bạn đang hỏi về. Tuy nhiên, đối với độ dài cố định nhỏ như 10, phương pháp của bạn sẽ nhanh chóng.


Nếu chỉ có một chiều dài cố định nhỏ như 10.
C. Ross
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.