There is a .bin file containing an array of numbers:

new int[] { 12, 6, 7, -1, 5, 15, 6, 4, -1, 15, 5 } 

There is a method that, in a cycle, searches for a local minimum and changes its sign to the opposite:

 private static void doWork() { try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw")) { int n = (int)raf.length() / Integer.BYTES; // Кол-во int prevValue = raf.readInt(); // пред. элемент. for (int i = 1; i < n - 1; i++) { // текущий элемент. int value = raf.readInt(); // позиция текущего элемента long pos = raf.getFilePointer(); // следующий элемент. int nextValue = raf.readInt(); if (value < prevValue && value < nextValue) { raf.seek(pos); raf.writeInt(-value); } } // for i } catch (Exception ex) { ex.printStackTrace(); } } // doWork 

But it does not work properly: it only changes the sign once for the opposite, and then with the prev. number to local minimum.

What have I done wrong?

  • these are three numbers 6 , -1 , -1 . The local minimum is where the derivative changes the sign from minus to plus. - vp_arth
  • Alakay, look closely at the state of your variables at the second iteration. - vp_arth
  • The local minimum is a number for which both neighbors are to the left and to the right by value greater than the number in the center. - Kryshtop
  • By the way, but in the situation 6,-1,-1,2 what to do? - rjhdby

2 answers 2

  1. prevValue value prevValue not updated.
  2. The pos is the position of the next element, not the current
  3. Running the code results in an EOFException due to the fact that in each iteration the file is shifted by 8 bytes, not 4.

To correct problems from points 2 and 3, it is necessary to take into account that each call to the readInt method results in a 4 byte offset.

As a result, the corrected code is as follows:

 private static final String FILE_NAME = "test.txt"; private static void doWork() { try (RandomAccessFile raf = new RandomAccessFile(FILE_NAME, "rw")) { int n = (int)raf.length() / Integer.BYTES; // Кол-во int prevValue = raf.readInt(); // пред. элемент. for (int i = 1; i < n - 1; i++) { // позиция текущего элемента long pos = raf.getFilePointer(); //исправление пункта 2 // текущий элемент. int value = raf.readInt(); // следующий элемент. int nextValue = raf.readInt(); if (value < prevValue && value < nextValue) { raf.seek(pos); raf.writeInt(-value); } else //исправление пункта 3 { raf.seek(pos + Integer.BYTES); } prevValue = value; //исправление пункта 1 } // for i } catch (Exception ex) { ex.printStackTrace(); } } // doWork 

However, you can not read each number twice: read only nextValue , and prevValue and value from the previous iteration:

 private static void doWork() { try (RandomAccessFile raf = new RandomAccessFile(FILE_NAME, "rw")) { int numbersCount = (int)raf.length() / Integer.BYTES; if (numbersCount < 3) { return; } int prevValue = raf.readInt(); int value = raf.readInt(); for (int i = 2; i < numbersCount; i++) { int nextValue = raf.readInt(); if (value < prevValue && value < nextValue) { long savedPos = raf.getFilePointer(); raf.seek(savedPos - 2 * Integer.BYTES); raf.writeInt(-value); raf.seek(savedPos); } prevValue = value; value = nextValue; } } catch (Exception ex) { ex.printStackTrace(); } } 

    The main error is that you do not update the prevValue value in the following iterations.

    Sample implementation without files:

     public class Task { private int[] numbers; public Task(int[] numbers){ this.numbers = numbers;} public void transform() { int prev = numbers[0]; for (int i = 1; i < numbers.length - 1; i++) { int current = numbers[i]; int next = numbers[i+1]; if (current < next && current < prev) { numbers[i] = -numbers[i]; } prev = current; // <-- Это важно } } public void print() { for (int i = 0; i < numbers.length; i++) { System.out.print(numbers[i] + " "); } System.out.print("\n"); } } public class Main { public static void main(String[] args) { int[] input = new int[]{ 12, 6, 7, -1, 5, 15, 6, 4, -1, 15, 5 }; Task task = new Task(input); task.print(); // 12 6 7 -1 5 15 6 4 -1 15 5 task.transform(); task.print(); // 12 -6 7 1 5 15 6 4 1 15 5 task.transform(); task.print(); // 12 6 7 -1 5 15 6 4 -1 15 5 } }