Нахождение индекса массива, состоящего из нескольких объединенных подмассивов

#java #arrays

Вопрос:

В этом запросе не используется 2D-массив. Рассмотрим 1D-массив следующей структуры, в котором индексы основаны на нуле, а длины-на единице:

Раздел 0 представляет собой массив из одной ячейки.

Раздел 1

  • Подмножество 1
    • Указатель 0
    • Указатель 1
    • Указатель n - 1
  • Подмножество 2
    • Указатель 0
    • Указатель 1
    • Указатель n - 1
  • Подмножество k
    • Указатель 0
    • Указатель 1
    • Указатель m - 1

Разделы 2 и 3 имеют ту же структуру, что и Раздел 1.

Существует несколько массивов, которые объединены вместе, чтобы имитировать более крупный. В общей сложности всегда будет четыре секции: секция 0 всегда будет иметь одну ячейку, секции 1, 2 и 3 будут иметь k подмассив. Подмассивы 1 до k-1 (за исключением последнего подмассива) будут иметь длину n . Последний подмассив будет содержать m элементы и m < n .

Цель: учитывая накопительный индекс на основе нуля input , найдите соответствующий индекс, который находится в подмассиве раздела, используя формулы индекса, минимальное количество if операторов и без циклов.

Вот пример:

  • Позвольте k = 3 , n = 8 и m = 5 чтобы все было основано на одном. Вот правильный вывод для разделов 0 и 1:
  input =  0 → section = 0, array = 0, subIndex = 0

 input =  1 → section = 1, array = 0, subIndex = 0
 input =  2 → section = 1, array = 0, subIndex = 1
 input =  3 → section = 1, array = 0, subIndex = 2
 input =  4 → section = 1, array = 0, subIndex = 3
 input =  5 → section = 1, array = 0, subIndex = 4
 input =  6 → section = 1, array = 0, subIndex = 5
 input =  7 → section = 1, array = 0, subIndex = 6
 input =  8 → section = 1, array = 0, subIndex = 7
 input =  9 → section = 1, array = 1, subIndex = 0
 input = 10 → section = 1, array = 1, subIndex = 1
 input = 11 → section = 1, array = 1, subIndex = 2
 input = 12 → section = 1, array = 1, subIndex = 3
 input = 13 → section = 1, array = 1, subIndex = 4
 input = 14 → section = 1, array = 1, subIndex = 5
 input = 15 → section = 1, array = 1, subIndex = 6
 input = 16 → section = 1, array = 1, subIndex = 7
 input = 17 → section = 1, array = 2, subIndex = 0
 input = 18 → section = 1, array = 2, subIndex = 1
 input = 19 → section = 1, array = 2, subIndex = 2
 input = 20 → section = 1, array = 2, subIndex = 3
 input = 21 → section = 1, array = 2, subIndex = 4
 

The next entries should be:

 input = 22 → section = 2, array = 0, subIndex = 0
...
input = 30 → section = 2, array = 1, subIndex = 0
...
input = 38 → section = 2, array = 2, subIndex = 0
...
input = 42 → section = 2, array = 2, subIndex = 4

input = 43 → section = 3, array = 0, subIndex = 0
...
input = 51 → section = 3, array = 1, subIndex = 0
...
input = 59 → section = 3, array = 2, subIndex = 0
...
input = 63 → section = 3, array = 2, subIndex = 4
 

На данный момент мои формулы с одним if оператором могут получить только первый раздел (не раздел 2 или 3). Надежда состоит в том, чтобы найти набор формул для достижения цели без использования if операторов или циклов. Вот что у меня есть до сих пор:

 public class Test {

    public Test() {
        for (int i = 0; i < 63; i  ) {
            getIndex(i);
        }
    }

    public void getIndex(int i) {
        if (i == 0) {//Aligns output. I couldn't factor it in the formula
            System.out.println("input = "   i   " → "  
                    "section = "   0  
                    ", array = "   0  
                    ", subIndex = "   0);
            return;
        }
        int k             = 3;//Number of subarrays for each section
        int n             = 8;//all subarray sizes except last one
        int m             = 5;//last subarray size
        int sectionLength = (k - 1) * n   m;//number of cells in a single
                                            //section (other than section 0).

        //obtaining the values:
        int section  = (i - 1) / sectionLength   1;//the section (1, 2 or 3)
        int subarray = (i - 1) / (section * n);
        int index    = ((i - 1) % n);
        System.out.println("input = "   i   " → "  
                "section = "   section  
                ", array = "   subarray  
                ", subIndex = "   index);
    }

    public static void main(String[] args) {
        Test t = new Test();
    }
}
 

Ответ №1:

 public class Test {
    public static void main(String[] args) {
        
        // all your constants
        final int TOTAL_SECTION = 63;
        final int SUBARRAY_PER_SECTION = 3;
        final int SUBARRAY_SIZE = 8;
        final int FINAL_SUBARRAY_SIZE = 5;

        // keep track of current input number, increase one after each input
        int inputNumber = 0;

        for (int i = 0; i < TOTAL_SECTION; i  ) {
            
            // if it is 0, all the value is 0, so just print the defualt format with all 0
            if (i == 0) {
                print(inputNumber  , 0 , 0, 0);
                System.out.println();
                continue;
            }

            for (int j = 0; j < SUBARRAY_PER_SECTION; j  ) {
                
                // if it is last subarray, use the final subarray size
                if (j == SUBARRAY_PER_SECTION - 1) {
                    for (int k = 0; k < FINAL_SUBARRAY_SIZE; k  ) {
                        print(inputNumber  , i, j, k);
                    }
                    break;
                }

                // otherwise, just use the normal subarray size
                for (int k = 0; k < SUBARRAY_SIZE; k  ) {
                    print(inputNumber  , i, j, k);
                }
            }

            // print a new line after each section done
            System.out.println();
        }
    }

    // format of the message, use this method and give the 4 values needed as parameters
    private static void print(int inputNumber, int sectionNumber, int arrayNumber, int subIndex) {
        System.out.printf("input = - → section = %d, array = %d, subIndex = %d %n", inputNumber, sectionNumber, arrayNumber, subIndex);
    }
}