Сколько символов может иметь строка Java?


157

Я пытаюсь решить проблему следующего палиндрома из Sphere Online Judge (SPOJ), где мне нужно найти палиндром с целым числом до миллиона цифр. Я думал об использовании функций Java для реверсирования строк, но позволят ли они, чтобы строка была такой длинной?


Вы говорите, что вам нужно написать функцию, которая генерирует палиндромы, размер которых определяется пользователем и может быть длиной до 1 миллиона символов?
Роберт

3
Проблема (от SPOJ) может содержать файл 100Gigabyte, и вы хотите , чтобы загрузить его в строку сразу? Серьезно ... пожалуйста, используйте сканер!
Мрачное

Ответы:


242

Вы должны быть в состоянии получить строку длины

  1. Integer.MAX_VALUEвсегда 2 147 483 647 (2 31 - 1)
    (определяется спецификацией Java, максимальный размер массива, который класс String использует для внутреннего хранения)
    ИЛИ

  2. Half your maximum heap size(поскольку каждый символ составляет два байта), в зависимости от того, что меньше .


43
... или ваш максимальный размер кучи, деленный на 2 ..., так как символ 2 байта
ChssPly76

2
@ ChssPly76: Да, это правильно. Я отредактировал свой ответ, спасибо.
Билл Ящерица

2
как узнать максимальный размер кучи? Кроме того, я не знаю, какая виртуальная машина Java, используемая судьей для проверки моей проблемы, является частью Integer.MAX_VALUE спецификации JVM?
andandandand

6
Integer.MAX_VALUE всегда 2147483647 (2 ^ 31 - 1), это часть спецификации Java.
cd1

4
Предполагается, что 64-битная JVM требует 8 ГБ виртуальной памяти для хранения строки такой длины.
Роберт Фрейзер

21

Я полагаю, что они могут содержать до 2 ^ 31-1 символов, поскольку они хранятся во внутреннем массиве, а массивы индексируются целыми числами в Java.


Внутренняя реализация не имеет значения - нет причины, по которой, например, символьные данные не могут быть сохранены в массиве long. Проблема в том, что интерфейс использует целочисленные значения длины. getBytesи подобное может иметь проблемы, если вы попытаетесь использовать очень большую строку.
Том Хотин - Tackline

Это правда - я имел в виду этот факт. Виноват.
Аперкинс

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 Strings будет использовать byte [], что будет означать, что многобайтовые символы будут использовать более одного байта и дополнительно уменьшать максимум. Если у вас есть все четыре байтовых кода, например, эмодзи, вы получите только около 500 миллионов символов


2
Компактные строки в Java 9 используют кодировку Latin-1 или UTF-16. Нет кодирования переменной длины, то есть нет трехбайтовых символов.
Апангин

@apangin "Не стоит использовать альтернативные кодировки, такие как UTF-8", спасибо за исправление.
Питер Лори

5

Рассматривали ли вы использовать BigDecimalвместо того, Stringчтобы держать свои номера?


1
Это зависит от того, что приложение собирается делать с числами. Если он собирается просто выполнять текстовые операции, такие как поиск палиндромов, подсчет (десятичных) цифр, тогда строка лучше. Если это будет делать арифметику, лучше использовать BigDecimal (или BigInteger).
Стивен С

Проблема в том, что «Для каждого K выведите наименьший палиндром больше, чем K.» (где K - заданное число). Было бы тривиально просто вывести первый палиндром, меньший, чем K. Вам понадобится арифметика, чтобы найти один, больший, чем K. Пример: найдите следующий палиндром, больший, чем 999999999999, или следующий палиндром, превышающий 12922.
Thorbjørn Ravn Andersen

4

Integer.MAX_VALUE - это максимальный размер строки + зависит от объема вашей памяти, но проблема в сфере онлайн судить, вам не нужно использовать эти функции


3

Java9 использует byte [] для хранения String.value, поэтому вы можете получить только около 1 Гб строк в Java9. Java8, с другой стороны, может иметь строки 2 ГБ.

Под символом я подразумеваю «символы», некоторые символы не могут быть представлены в BMP (например, некоторые смайлики), поэтому потребуется больше (в настоящее время 2) символов.


4
Не могли бы вы приложить ссылку на ограничение размера строки Java-9 до 1 ГБ с 2 ГБ
Адитья Гупта

-1

Куча часть становится хуже, друзья мои. UTF-16 не может быть ограничен 16 битами и может расширяться до 32


2
За исключением того, что charтип Java точно равен 16 битам, поэтому количество битов, используемых UTF-16, не имеет значения ...
awksp
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.