Java String มีอักขระได้จำนวนเท่าใด


157

ฉันกำลังลองปัญหาThe Next Palindromeจาก Sphere Online Judge (SPOJ) ที่ฉันต้องการค้นหา palindrome สำหรับจำนวนเต็มสูงถึงหลักล้าน ฉันคิดเกี่ยวกับการใช้ฟังก์ชั่นของ Java ในการย้อนกลับสตริง แต่พวกเขาจะอนุญาตให้ String ยาวหรือไม่


คุณกำลังบอกว่าคุณต้องเขียนฟังก์ชั่นที่สร้าง palindromes ขนาดที่ผู้ใช้ระบุและมีความยาวสูงสุด 1 ล้านตัวอักษร?
Robert

3
ปัญหา (จาก Spoj) อาจมีไฟล์ 100Gigabyte และคุณชอบที่จะโหลดลงในสตริงในครั้งเดียว? อย่างจริงจัง ... โปรดใช้สแกนเนอร์!
กลัว

คำตอบ:


242

คุณควรจะได้ความยาวของสตริง

  1. Integer.MAX_VALUE2,147,483,647เสมอ(2 31 - 1)
    (กำหนดโดยข้อมูลจำเพาะ Java ขนาดสูงสุดของอาร์เรย์ซึ่งคลาส String ใช้สำหรับหน่วยเก็บข้อมูลภายใน)
    หรือ

  2. Half your maximum heap size(ตั้งแต่ตัวละครแต่ละตัวเป็นสอง bytes) แล้วแต่จำนวนใดจะมีขนาดเล็กลง


43
... หรือขนาดฮีพสูงสุดของคุณหารด้วย 2 ... เนื่องจากอักขระคือ 2 ไบต์
ChssPly76

2
@ ChssPly76: ใช่ถูกต้อง ฉันแก้ไขคำตอบของฉันขอบคุณ
Bill the Lizard

2
ฉันจะหาขนาดฮีปสูงสุดได้อย่างไร นอกจากนี้ฉันไม่รู้ว่า Java virtual machine ตัวใดที่ผู้พิพากษาใช้เพื่อทดสอบปัญหาของฉันคือ Integer.MAX_VALUE ส่วนหนึ่งของข้อมูลจำเพาะของ JVM ขึ้นอยู่กับอะไร
andandandand

6
Integer.MAX_VALUE เสมอ 2147483647 (2 ^ 31 - 1) นั่นเป็นส่วนหนึ่งของข้อกำหนด Java
cd1

4
สมมติ JVM 64 บิตเนื่องจากคุณต้องการหน่วยความจำเสมือน 8GB เพื่อจัดเก็บสตริงที่มีความยาวนั้น
Robert Fraser

21

ฉันเชื่อว่าพวกเขาสามารถมีอักขระได้สูงสุด 2 ^ 31-1 เนื่องจากมีอาร์เรย์ภายในอยู่และอาร์เรย์จะถูกทำดัชนีโดยจำนวนเต็มใน Java


การใช้งานภายในนั้นไม่เกี่ยวข้อง - ไม่มีเหตุผลใดที่ข้อมูลตัวอักษรไม่สามารถจัดเก็บในอาร์เรย์ที่มีความยาวได้ ปัญหาคืออินเตอร์เฟสใช้ ints สำหรับความยาว getBytesและที่คล้ายกันอาจมีปัญหาหากคุณลองสตริงที่มีขนาดใหญ่มาก
Tom Hawtin - tackline

นั่นเป็นความจริง - ฉันหมายถึงข้อเท็จจริงนั้น ความผิดฉันเอง.
aperkins

15

ในขณะที่คุณสามารถทำได้ในทฤษฎี Integer.MAX_VALUE ตัวละคร JVM นั้นถูก จำกัด ขนาดของอาเรย์ที่มันสามารถใช้ได้

public static void main(String... args) {
    for (int i = 0; i < 4; i++) {
        int len = Integer.MAX_VALUE - i;
        try {
            char[] ch = new char[len];
            System.out.println("len: " + len + " OK");
        } catch (Error e) {
            System.out.println("len: " + len + " " + e);
        }
    }
}

บนการอัปเดต Oracle Java 8 92

len: 2147483647 java.lang.OutOfMemoryError: Requested array size exceeds VM limit
len: 2147483646 java.lang.OutOfMemoryError: Requested array size exceeds VM limit
len: 2147483645 OK
len: 2147483644 OK

หมายเหตุ: ใน Java 9 สตริงจะใช้ไบต์ [] ซึ่งหมายความว่าอักขระหลายไบต์จะใช้มากกว่าหนึ่งไบต์และลดค่าสูงสุดให้มากขึ้น หากคุณมีรหัสจุดสี่ไบต์เช่น emojis คุณจะได้รับประมาณ 500 ล้านตัวอักษร


2
Compact Stringsใน Java 9 ใช้การเข้ารหัส Latin-1 หรือ UTF-16 ไม่มีการเข้ารหัสความยาวตัวแปรนั่นคือไม่มีอักขระสามไบต์
apangin

@apangin "ไม่ใช่เป้าหมายที่จะใช้การเข้ารหัสทางเลือกเช่น UTF-8" ขอบคุณสำหรับการแก้ไข
Peter Lawrey

5

คุณคิดว่าจะใช้BigDecimalแทนStringการถือตัวเลขของคุณหรือไม่?


1
ขึ้นอยู่กับว่าแอปพลิเคชันจะทำอะไรกับตัวเลข ถ้ามันจะทำสิ่งที่เป็นข้อความเช่นการค้นหา palindromes, การนับ (ทศนิยม) หลัก, ดังนั้น String จะดีกว่า ถ้ามันกำลังจะทำเลขคณิต BigDecimal (หรือ BigInteger) จะดีกว่า
สตีเฟ่นซี

ปัญหาคือ "สำหรับแต่ละ K เอาต์พุต palindrome ที่เล็กที่สุดที่ใหญ่กว่า K. " (โดยที่ K คือหมายเลขที่ระบุ) มันจะง่ายเล็กน้อยที่จะส่งออก palindrome แรกที่เล็กกว่า K คุณต้องใช้เลขคณิตเพื่อหาอันที่ใหญ่กว่า K ตัวอย่าง: ค้นหา palindrome ถัดไปที่มีขนาดใหญ่กว่า 999999999999 หรือ palindrome ถัดไปที่มีขนาดใหญ่กว่า 12922
Thorbjørn Ravn Andersen

4

Integer.MAX_VALUE คือขนาดสูงสุดของสตริง + ขึ้นอยู่กับขนาดหน่วยความจำของคุณ แต่ปัญหาจากการตัดสินออนไลน์ของทรงกลมที่คุณไม่ต้องใช้ฟังก์ชั่นเหล่านั้น


3

Java9 ใช้ byte [] เพื่อเก็บ String.value ดังนั้นคุณจะได้รับ 1GB Strings ใน Java9 เท่านั้น Java8 ในอีกทางหนึ่งสามารถมี 2GB Strings

โดยตัวละครฉันหมายถึง "ตัวอักษร" อักขระบางตัวไม่สามารถใช้แทน BMP (เช่นอิโมจิบางตัว) ดังนั้นมันจะใช้ตัวอักษร (ปัจจุบัน 2) มากขึ้น


4
คุณสามารถแนบการอ้างอิงสำหรับ Java-9 การ จำกัด ขนาดสตริงเป็น 1 GB จาก 2 GB ได้
ไหม

-1

ส่วนกองก็แย่ลงเพื่อนของฉัน UTF-16 ไม่รับประกันว่าจะถูก จำกัด ไว้ที่ 16 บิตและสามารถขยายได้ถึง 32


2
ยกเว้นของ Java charประเภทเป็น 16 บิตตรงดังนั้นจำนวนของบิต UTF-16 ใช้ไม่ได้เรื่องจริงๆ ...
awksp
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.