web-dev-qa-db-ja.com

配列を動的に割り当てて成長させる方法

プロジェクトに取り組んでいますが、既存のJavaデータ構造(ArraysList、treesなど)は使用できません。

配列しか使用できません。したがって、新しいメモリでアレイを動的に更新する必要があります。

テキストファイルから読み取り、配列メモリに100を事前に割り当てます。

   String [] wordList;
   int wordCount = 0;
   int occurrence = 1;
   int arraySize = 100;
   wordList = new String[arraySize];
   while ((strLine = br.readLine()) != null)   {
         // Store the content into an array
         Scanner s = new Scanner(strLine);
         while(s.hasNext()) {
           wordList[wordCount] = s.next();
           wordCount++;
         } 
   }

現在、これは100個未満のリストアイテムに対して正常に機能します。 br.readlineは、テキストファイルの各行を通過するバッファー付きリーダーです。次に、各Wordをリストに保存し、インデックス(wordCount)をインクリメントします。

ただし、100を超えるアイテムを含むテキストファイルを取得すると、割り当てエラーが発生します。

この配列を動的に更新するにはどうすればよいですか(それにより、車輪を再発明しますか)?

ありがとう!

9
Zack Tanner

次のようなことができます:

_String [] wordList;
int wordCount = 0;
int occurrence = 1;
int arraySize = 100;
int arrayGrowth = 50;
wordList = new String[arraySize];
while ((strLine = br.readLine()) != null)   {
     // Store the content into an array
     Scanner s = new Scanner(strLine);
     while(s.hasNext()) {
         if (wordList.length == wordCount) {
              // expand list
              wordList = Arrays.copyOf(wordList, wordList.length + arrayGrowth);
         }
         wordList[wordCount] = s.next();
         wordCount++;
     } 
}
_

Java.util.Arrays.copyOf(String[])を使用することは、基本的に次と同じことをしています:

_if (wordList.length == wordCount) {
    String[] temp = new String[wordList.length + arrayGrowth];
    System.arraycopy(wordList, 0, temp, 0, wordList.length);
    wordList = temp;
}
_

ただし、3行ではなく1行のコードです。 :)

18
Ted Hopp

新しい配列(たとえば容量の2倍)を割り当て、すべての要素をそこに移動します。

基本的に、wordCountwordList.size()にヒットするかどうかを確認する必要があります。ヒットすると、前の配列の2倍の長さで新しい配列を作成し、すべての要素をそれにコピーします(これを行うための補助メソッドを作成します)、wordListを新しい配列に割り当てます。

内容をコピーするには、could use System.arraycopy、しかし、それがあなたの制限で許可されているかどうかはわかりませんので、要素を一つずつ単純にコピーすることができます:

public String[] createNewArray(String[] oldArray){
    String[] newArray = new String[oldArray.length * 2];
    for(int i = 0; i < oldArray.length; i++) {
        newArray[i] = oldArray[i];
    }

    return newArray;
}

続行します。

5
pcalcao

Java ArrayList の実装を見てください。 Java ArrayListは内部で固定サイズの配列を使用し、要素の数が現在のサイズを超えると配列を再割り当てします。同様の行に実装することもできます。

3
MoveFast

新しいarrayにコピーした場合、配列サイズを動的に増やすことはできません。使用する System.arrayCopyそのためには、各要素を新しい配列にコピーするよりも優れています。参考のため なぜJavaでSystem.arraycopyがネイティブなのですか?

private static Object resizeArray (Object oldArray, int newSize) {
   int oldSize = Java.lang.reflect.Array.getLength(oldArray);
   Class elementType = oldArray.getClass().getComponentType();
   Object newArray = Java.lang.reflect.Array.newInstance(
         elementType, newSize);
   int preserveLength = Math.min(oldSize, newSize);
   if (preserveLength > 0)
      System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
   return newArray;
}

新しい大きな配列を手動で作成し、アイテムをコピーする必要があります。

this が役立つ場合があります

0

Visual BasicにはNice関数があります:ReDim Preserve

誰かが親切に同等の関数を書いています-あなたはそれを見つけることができます ここ 。私はそれがあなたが求めているものとまったく同じだと思います(そしてあなたは車輪を再発明しているのではなく、あなたは他の誰かのものをコピーしています)...

0
Floris

1つの要素の配列があり、100万の要素を動的に収容できるようにサイズを拡張する場合を考えてみましょう。

事例1:

String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 1];
for(int i = 0; i < wordList.length ; i++){
    tmp[i] = wordList[i];
}
wordList = tmp;

ケース2(追加要因によるサイズの増加):

String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 10];
for(int i = 0; i < wordList.length ; i++){
    tmp[i] = wordList[i];
}
wordList = tmp;

ケース3(増倍率によるサイズの増加):

String [] wordList = new String[1];
String [] tmp = new String[wordList.length * 2];
for(int i = 0; i < wordList.length ; i++){
    tmp[i] = wordList[i];
}
wordList = tmp;

配列のサイズを動的に拡張する場合、Array.copyを使用するか、配列を反復処理し、forループを使用して要素を新しい配列にコピーすると、実際には配列の各要素を反復処理します。これはコストのかかる操作です。 Array.copyはクリーンで最適化されますが、それでもコストがかかります。したがって、乗算係数によって配列の長さを増やすことをお勧めします。

どのように役立つか、

ケース1では、100万の要素を収容するために、配列のサイズを100万から1倍、つまり999,999倍に増やす必要があります。

ケース2では、アレイのサイズを100万/ 10-1倍、つまり99,999倍に増やす必要があります。

ケース3では、ログによって配列のサイズを増やす必要があります2100万-1回、つまり18.9(仮に)。

0
Ashwin Aggarwal
public class Arr {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int a[] = {1,2,3};
        //let a[] is your original array
        System.out.println(a[0] + " " + a[1] + " " + a[2]);
        int b[];
        //let b[] is your temporary array with size greater than a[]
        //I have took 5
        b = new int[5];
        //now assign all a[] values to b[]
        for(int i = 0 ; i < a.length ; i ++)
            b[i] = a[i];
        //add next index values to b
        b[3] = 4;
        b[4] = 5;
        //now assign b[] to a[]
        a = b;
        //now you can heck that size of an original array increased
        System.out.println(a[0] + " " + a[1] + " " + a[2] + " " + a[3] + " " 
    + a[4]);
    }

}

上記のコードの出力は次のとおりです。

1 2 3

1 2 3 4 5

0
Aitha Ranjeeth