Целостность стека устанавливается в одно значение - PullRequest
0 голосов
/ 28 марта 2011

У меня довольно сложная проблема.Я программирую для Android и пытаюсь получить комбинации целых чисел.Я написал код для генерации комбо и отследил его с помощью удаленного отладчика, и он, кажется, работает правильно.Это работает, помещая каждую новую комбинацию в стек.Тем не менее, каждая комбинация в стеке обновляется с каждым изменением активного массива, который неоднократно изменяется и фиксируется в стеке в нескольких формах.Я полагаю, что проблема связана с моими новыми комбо, содержащими указатели на исходный массив, а не копии содержимого массива во время создания комбо.Однако я не уверен, как решить проблему.

Все советы приветствуются, и спасибо за ваше время.

/**
 * 
 * @param comboSize
 *            The desired size of combo
 * @param values
 *            The dataset we are finding the values of; must be ints
 * @return an array containing all possible combos of comboSize for values
 */
private Combo[] getCombos(int comboSize, int[] values) {

    Stack<Combo> combos = new Stack<Combo>();
    // combos.ensureCapacity((int) Math.pow(values.length, comboSize) + 1);

    getIntArrayZeroToTarget(values.length - 1);

    int[] temp = getIntArrayZeroToTarget(comboSize-1);
    // System.arraycopy(surrogates, 0, temp, 0, comboSize);

    combos.push(new Combo(temp));

    // int workIndex = comboSize-1;

    //Evil things lurked in this code. Two days evaporated during mortal combat with it. I surrendered.

    switch (comboSize){
        case 2: for (int i = 0; i < values.length; i++){
            for (int j = i+1; j < values.length; j++){
                temp[0] = i;
                temp[1] = j;
                combos.push(new Combo(temp));
            }
        } break;
        case 3: for (int i = 0; i < values.length; i++){
            for (int j = i+1; j < values.length; j++){
                for (int k = j+1; k < values.length; k++){
                    temp[0] = i;
                    temp[1] = j;
                    temp[2] = k;
                    combos.push(new Combo(temp));
                }
            }
        } break;        
        case 4: for (int i = 0; i < values.length; i++){
            for (int j = i+1; j < values.length; j++){
                for (int k = j+1; k < values.length; k++){
                    for (int l = k+1; l < values.length; l++){
                        temp[0] = i;
                        temp[1] = j;
                        temp[2] = k;
                        temp[3] = l;
                        combos.push(new Combo(temp));                   
                    }
                }
            }
        } break;
    }

    //This code converts the psudoCombos (which contain the indices of the values) to combos that contain the actual values from the user
    Stack<Combo> cCombos = new Stack<Combo>();

    while (!combos.isEmpty()) {
        int[] temp1 = combos.pop().getContents();
        int[] temp2 = new int[temp1.length];

        for (int i = 0; i < temp1.length; i++)
            temp2[i] = values[temp1[i]];

        cCombos.push(new Combo(temp2));

    }

    Combo[] aCombos = new Combo[cCombos.size()];

    for (int i = 0; !cCombos.isEmpty(); i++){ //I spent about 7 hours debugging this code because I was missing the c in cCombos here...
        aCombos[i] = cCombos.pop();

    }
    String[] tempS = new String[aCombos.length];
    for (int i = 0; i < aCombos.length; i++){
        tempS[i] = aCombos[i].toString();
    }

    combosAsStrings = tempS;

    return aCombos;
}

1 Ответ

0 голосов
/ 28 марта 2011

Вы правы, говоря, что ваша проблема связана с объектами Combo, ссылающимися на один и тот же массив. Чтобы это исправить, просто выделите новый массив перед каждым созданным вами комбинированным объектом. Таким образом, в каждом внутреннем цикле for оператора switch ставьте эту строку первой:

temp = new int[comboSize];

Это должно решить твою проблему. (В качестве альтернативы вы можете использовать конструктор по умолчанию Combo, просто создав новый массив и скопировав массив, который был ему передан, в новый.)

Итак, есть ваша проблема, но вот несколько советов:

Первый: «Двухэтапный» подход к решению этой проблемы может быть объединен в один, если вы просто ссылаетесь на массив values ​​[] во внутреннем цикле for оператора switch. Например, в первом цикле for, в случае 2, замените соответствующие строки на:

temp[0] = values[i];
temp[1] = values[j];

затем нажмите комбо. Это избавляет от необходимости делать «второй проход», переходящий от псевдо-комбинаций к реальным, и устраняет необходимость в третьем цикле aCombos, который, как я предполагаю, вы используете, чтобы просто вернуться к исходному порядку комбинаций ( так как второй проход проходит в обратном порядке.)

Второе: Вы можете устранить необходимость использования оператора switch / case и повторяющегося кода, используя рекурсивную функцию. Это выходит за рамки вопроса, но оно также позволит вам поддерживать комбинации любого количества значений, а не только чисел, которые вы жестко кодируете (в настоящее время их число равно четырем).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...