2016-08-22 2 views
2

임시 배열을 만들지 않고 배열 배열에서 배열을 읽는 알고리즘을 작성하는 데 어려움이 있습니다.배열 배열에서 임의 길이 배열 읽기

[data correspond to a byte[][] that contains the data we want to read from] 
[each arrays can be of arbitrary sizes. No assumption can be done there] 
[limit is the sum of bytes that has been wrote to data beforehand. (Appending an array of size X increment limit by X - 1)] 
[position is the current position that has been read by previous calls to read(...)] 

1) Skip until array that belongs to position is reached 
2) Copy from saved position in the array to the output array 
3) Move to next array 
4) Copy as much bytes as we can into the output buffer 
5) Repeat 3-4 until output buffer is filled with the proper amount of data or we've reached the end of the data. 

예 (POS = 12, 길이 = 16) : 어떤 도움

[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] // Skip this row as pos > row.length 
[ ][ ][X][X][X][X][X]   // Read from position 2 (row.length - relative pos) until end of array 
[X][X][X][X][X][X][X][X]  // Read entire array as length left > row.length 
[X][X][X][ ][ ][ ][ ][ ][ ] // Read from 0 to length left (aka 3) 
[ ][ ][ ][ ][ ][ ][ ][ ] 
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] 

감사

여기에 내 생각이다!

+0

* 당신이 더 많은 설명 할 수 * "그것은 작동하지 않는 것 같다"? 무슨 일 이니? – 4castle

+0

나는이 방법을 실행할 때 적절한 순서를 출력하지 않는다는 것을 의미한다. 하지만 그것에 대해 생각하고 있었는데, 나는 srcOffset & position에서 엉망이라고 생각한다. 포인터가 움직이지 않기 때문에, 위치 포인터가 잘못된 값을 준다. – Romain

답변

0

여기에 내가 종료 업 사용하여 구현 :

public int read(byte[] into, int dstOffset, int length) { 
    if (!isComplete()) { 
     throw new IllegalStateException("Data is not complete yet"); 
    } 

    int pointer = 0; 
    int byteRead = 0; 
    int total = 0; 

    if (VERBOSE) 
     Dog.d("Array size : " + data.length + " ID : " + id); 
    for (int i = 0; i < data.length && (length > 0 || position >= limit); i++) { 
     if (position > (pointer + data[i].length)) { 
      pointer += data[i].length; 
      if (VERBOSE) 
       Dog.d("Skip -> I = " + i + ", Data length = " + data[i].length + ", Position = " + position + ", Pointer = " + pointer + ", Limit = " + limit); 
     } else { 
      if (VERBOSE) 
       Dog.d("I = " + i + ", Data length = " + data[i].length + ", Position = " + position + ", Pointer = " + pointer + ", Limit = " + limit); 
      // We are in the right array 
      int srcOffset = position - pointer; // This is the starting position in our target array 
      int relativeLimit = Math.min(limit - pointer, data[i].length); // The is the ending position in our target array 

      byteRead = Math.min(relativeLimit - srcOffset, length); // Now the number is the byte read is either the number between start and end or the requested length 

      if (VERBOSE) 
       Dog.d("I = " + i + ", srcOffset = " + srcOffset + ", dstOffset = " + dstOffset + ", byteRead = " + byteRead + " out of " + data[i].length + " (limit is = " + limit + ", pointer = " + pointer + ")"); 
      System.arraycopy(data[i], srcOffset, into, dstOffset, byteRead); 

      length -= byteRead; // We've read X bytes, so we still have to read (length - X) 
      dstOffset += byteRead; // We need to start next write at previous position + X 
      total += byteRead; // Counter to keep track of byte we've read 

      pointer += data[i].length; // Current read position 
      position += byteRead; // Current position 
      if (VERBOSE) 
       Dog.d("Left to write = " + length + ", byteRead = " + byteRead + ", total = " + total); 
     } 
    } 

    if (VERBOSE) 
     Dog.d("Wrote a total of :" + total); 
    return total; 
}