Bir Java String'in kaç karakteri olabilir?


157

Ben bir milyon haneye kadar bir tamsayı için bir palindrom bulmanız gereken Sphere Online Judge (SPOJ) sonraki Palindrome sorunu çalışıyorum . Dizeleri tersine çevirmek için Java'nın işlevlerini kullanmayı düşündüm, ancak bir String'in bu kadar uzun olmasına izin verecekler miydi?


boyutu kullanıcı tarafından belirtilen ve 1 milyon karakter uzunluğunda olabilen palindrom üreten bir işlev yazmanız gerektiğini mi söylüyorsunuz?
Robert

3
Sorun (SPOJ itibaren) bir 100Gigabyte dosya içerebilir ve bir kerede bir dize içine yüklemek ister? Cidden ... lütfen bir Tarayıcı kullanın!
Grim

Yanıtlar:


242

Bir uzunluk dizesi alabilmelisiniz

  1. Integer.MAX_VALUEher 2,147,483,647 (2 31 - 1)
    (Java tarifname tarafından tanımlanır, bir dizinin maksimum büyüklüğü, ki dahili depolama için String sınıfı kullanım)
    OR

  2. Half your maximum heap size(her karakter iki bayt olduğu için) hangisi daha küçükse .


43
... ya da maksimum yığın boyutunuz 2'ye bölünür ... çünkü karakter 2 bayttır
ChssPly76

2
@ ChssPly76: Evet, doğru. Cevabımı düzenledim, teşekkür ederim.
Kertenkele Bill

2
maksimum yığın boyutunu nasıl bulabilirim? Ayrıca, jürinin sorunumu test etmek için hangi java sanal makinesini kullandığını bilmiyorum. JVM'ye bağlı spec'in Integer.MAX_VALUE kısmı?
andandandand

6
Integer.MAX_VALUE her zaman 2147483647'dir (2 ^ 31-1), bu Java Spesifikasyonunun bir parçasıdır.
cd1

4
64 bit JVM varsayarsak, bu uzunlukta bir dizeyi saklamak için 8 GB sanal belleğe ihtiyacınız olacaktır.
Robert Fraser

21

Ben bir iç dizi tarafından tutulur ve diziler Java tamsayılar tarafından endekslenir gibi, 2 ^ 31-1 karakter kadar olabilir inanıyorum.


Dahili uygulama önemsizdir; örneğin, karakter verilerinin uzun bir dizi dizide saklanmasının bir nedeni yoktur. Sorun arayüz uzunluğunu ints kullanıyor olmasıdır. getBytesve çok büyük bir dize denerseniz benzer sorunları olabilir.
Tom Hawtin - tackline

Bu doğru - bu gerçeği ima ediyordum. Benim hatam.
aperkins

15

Teoride Integer.MAX_VALUE karakterlerini kullanabilirsiniz, ancak JVM kullanabileceği dizinin boyutuyla sınırlıdır.

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 güncellemesinde 92 baskı

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

Not: Java 9'da Dizeler, byte [] kullanır, bu da çok baytlı karakterlerin birden fazla bayt kullanacağı ve maksimum değeri daha da azaltacağı anlamına gelir. Emoji gibi dört baytlık kod noktanız varsa, yalnızca yaklaşık 500 milyon karakter alırsınız


2
Java 9'daki Compact Dizeler Latin-1 veya UTF-16 kodlamasını kullanır. Değişken uzunluk kodlaması yok, yani üç baytlık karakter yok.
apangin

@apangin "UTF-8 gibi alternatif kodlamalar kullanmak bir hedef değil" düzeltmesi için teşekkür ederiz.
Peter Lawrey

5

Numaralarınızı tutmak BigDecimalyerine kullanmayı düşündünüz mü String?


1
Uygulamanın sayılarla ne yapacağına bağlıdır. Sadece palindrom bulma, basamakları (ondalık) sayma gibi metinsel şeyler yapacaksa, bir String daha iyidir. Aritmetik yapacaksa, BigDecimal (veya BigInteger) daha iyidir.
Stephen C

Sorun "Her K için, K'dan daha büyük en küçük palindromu çıktı." (burada K verilen sayıdır). K'den daha küçük olan ilk palindromu çıkarmak çok basit olacaktır. K'den daha büyük olanı bulmak için aritmetik gerekir. Örnek: 999999999999'dan daha büyük bir sonraki palindromu veya 12922'den daha büyük bir sonraki palindromu bulun.
Thorbjørn Ravn Andersen

4

Integer.MAX_VALUE maksimum dize boyutudur + bellek boyutunuza bağlıdır, ancak kürenin çevrimiçi hakemindeki sorun bu işlevleri kullanmak zorunda değilsiniz


3

Java9, String.value değerini depolamak için byte [] kullanır, böylece Java9'da yalnızca yaklaşık 1 GB Dizeler elde edebilirsiniz. Java8 ise 2GB Dizgeye sahip olabilir.

Karakter olarak "char" ları kastediyorum, bazı karakter BMP'de (emojilerin bazıları gibi) temsil edilemez, bu yüzden daha fazla (şu anda 2) karakter alacaktır.


4
Java-9 için Dize boyutunu 2 GB'tan 1 GB'a sınırlayan referans ekleyebilir misiniz
Aditya Gupta

-1

Yığın kısmı kötüleşiyor arkadaşlar. UTF-16'nın 16 bit ile sınırlı olduğu garanti edilmez ve 32'ye kadar genişletilebilir


2
Java'nın chartürü tam olarak 16 bit dışında , bu yüzden UTF-16'nın kullandığı bit sayısı gerçekten önemli değil ...
awksp
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.