Подтвердить что ты не робот

Рефакторинг пропущенных меток

После того, как я убедился, что помеченные breaks/continue являются "nono" над здесь, мне нужна помощь, чтобы удалить ярлык из моего кода.

Я имею квадратную матрицу и вектор, который имеет одинаковую длину. У вектора уже есть некоторые значения в нем a, зависящие от значений в матрице, которые вектор изменяется в цикле.

Надеюсь, код-фрагмент в принципе понятен...

vectorLoop:
for( int idx = 0; idx < vectorLength; idx++) {
    if( conditionAtVectorPosition( v, idx ) ) continue vectorLoop;

    matrixLoop:
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue matrixLoop;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) continue vectorLoop;
    }
    setValueInVector( v, idx );
}     

Пожалуйста, убедите меня, что есть более читаемая/лучшая версия без ярлыков.

4b9b3361

Ответ 1

Посмотрите на представленные решения:

  • Все они выглядят менее читабельными, чем оригиналы, поскольку они включают в себя больше кода на механизм кода, а не на сам алгоритм

  • Некоторые из них сломаны или были до того, как они были отредактированы. Большинство из них - это тот факт, что людям приходится много думать о том, как писать код без ярлыков и ничего не сломать.

  • Некоторые из них имеют ограничение производительности за выполнение одного и того же теста дважды, что не всегда может быть тривиальным. Альтернативой этому является сохранение и прохождение вокруг булевых элементов, которое становится уродливым.

  • Рефакторинг соответствующей части кода в метод фактически не работает: он реорганизует, как код выложен в файле, но не влияет на его выполнение.

Все это заставляет меня поверить, что, по крайней мере, в случае с этим вопросом, как сформулировано, ярлык является правильным решением и не нуждается в рефакторинге. Конечно, есть случаи, когда метки используются неправильно и должны быть удалены. Я просто не думаю, что это должно рассматриваться как какое-то нерушимое правило.

Ответ 2

Легко, мой хороший человек.

for( int idx = 0; idx < vectorLength; idx++) {
  if( conditionAtVectorPosition( v, idx ) ) continue;

  for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
    if( anotherConditionAtVector( v, rowIdx ) ) continue;
    if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) break;
  }
  if( !conditionAtMatrixRowCol( m, rowIdx, idx ) )
    setValueInVector( v, idx );
}

EDIT: Совершенно верно, вы Андерс. Я также отредактировал свое решение, чтобы принять это во внимание.

Ответ 3

@Patrick вы принимаете вызов setValueInVector (v, idx); в конце второго цикла ОК. Если код должен быть идентичным, логически, его необходимо переписать примерно так:

for( int idx = 0; idx 

Ответ 4

От чтения вашего кода.

  • Я заметил, что вы устраняете недопустимые позиции вектора в conditionAtVectorPosition, после чего вы удаляете недопустимые строки в anotherConditionAtVector.
  • Кажется, что проверка строк в anotherConditionAtVector избыточна, поскольку любое значение idx равно, anotherConditionAtVector зависит только от индекса строки (при условии, что anotherConditionAtVector не имеет побочных эффектов).

Итак, вы можете сделать это:

  • Сначала введите правильные позиции, используя условиеAtVectorPosition (это допустимые столбцы).
  • Затем получите допустимые строки, используя anotherConditionAtVector.
  • Наконец, используйте conditionAtMatrixRowCol, используя допустимые столбцы и строки.

Надеюсь, это поможет.

Ответ 5

@Николас

Некоторые из них сломаны или были до того, как они были отредактированы. Самое главное - это тот факт, что   людям приходится много думать о том, как писать код без ярлыков, а не   сломайте что-нибудь.

У меня другая точка зрения: некоторые из них сломаны, потому что трудно понять поведение исходного алгоритма.

Я понимаю, что это субъективно, но у меня нет никаких проблем с чтением исходного алгоритма. Он короче и яснее предлагаемых замен.

Все рефакторинги в этом потоке эмулируют поведение метки с использованием других языковых функций - как будто вы портировали код на язык, на котором не было меток.

Ответ 6

Некоторые из них имеют ограничение производительности при выполнении одного и того же теста дважды, что не всегда может быть тривиальным. Альтернативой этому является сохранение и прохождение вокруг булевых элементов, которое становится уродливым.
Исполнение штрафа незначительно. Однако я согласен, что выполнение теста дважды не является хорошим решением.

Я считаю, что вопрос заключался в том, как удалить метки, а не как оптимизировать алгоритм. Мне показалось, что оригинальный плакат не знал о том, как использовать "продолжить" и "разбить" ключевые слова без ярлыков, но, конечно, мои предположения могут быть неправильными.

Когда дело доходит до производительности, сообщение не дает никакой информации о реализации других функций, поэтому, насколько я знаю, они могут также загружать результаты через FTP как состоящие из простых вычислений, встроенных компилятором.

Говоря, что выполнение одного и того же теста дважды не является оптимальным в теории.

РЕДАКТИРОВАТЬ: На второй взгляд пример на самом деле не ужасное использование меток. Я согласен, что "goto is no-no" , но не из-за такого кода. Использование меток здесь существенно не влияет на читаемость кода. Конечно, они не требуются и их можно легко опустить, но не использовать их просто потому, что "использование меток плохо" не является хорошим аргументом в этом случае. В конце концов, удаление ярлыков не делает код намного легче читать, как другие уже прокомментировали.

Ответ 7

Этот вопрос не касался оптимизации алгоритма, но в любом случае спасибо;-)

В то время, когда я это написал, я считал, что помеченное слово продолжается как читаемое решение.

Я спросил SO question о соглашении (с меткой во всех кепках или нет) для ярлыков в Java.

В основном каждый ответ сказал мне: "Не используйте их, всегда есть лучший способ! рефактор!". Поэтому я поставил этот вопрос, чтобы попросить более читаемое (и, следовательно, лучшее?) Решение.

До сих пор я не полностью убежден в представленных альтернативах.

Пожалуйста, не поймите меня неправильно. Ярлыки злые чаще всего.

Но в моем случае условные тесты довольно просты, и алгоритм взят из математической статьи и поэтому очень скоро не изменится в ближайшем будущем. Поэтому я предпочитаю, чтобы все соответствующие части были видимыми одновременно, вместо того, чтобы прокручивать другой метод, называемый checkMatrixAtRow (x).

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

Ответ 8

Я думаю, что помеченные петли настолько необычны, что вы можете выбрать любой способ маркировки для вас - то, что у вас там, делает ваши намерения с продолжением совершенно ясными.


После того, как вы предложили рефакторинг циклов в исходном вопросе и теперь видите код, о котором идет речь, я думаю, что у вас есть очень читаемый цикл.

То, что я себе представлял, было совсем другим фрагментом кода - на самом деле, на самом деле, я вижу, что он намного чище, чем я думал.

Извиняюсь за недоразумение.

Ответ 9

Это работает для вас? Я извлек внутренний цикл в метод CheckedEntireMatrix (вы можете назвать его лучше меня). Также моя java немного ржавая.. но я думаю, что она получает сообщение через

for( int idx = 0; idx < vectorLength; idx++) {
    if( conditionAtVectorPosition( v, idx ) 
    || !CheckedEntireMatrix(v)) continue;

    setValueInVector( v, idx );
}

private bool CheckedEntireMatrix(Vector v)
{
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
    }   
    return true;
}

Ответ 10

У Гишу есть правильная идея:

for( int idx = 0; idx < vectorLength; idx++) {
    if (!conditionAtVectorPosition( v, idx ) 
        && checkedRow(v, idx))
         setValueInVector( v, idx );
}

private boolean checkedRow(Vector v, int idx) {
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
    }  
    return true;
}

Ответ 11

Я не слишком уверен, чтобы понять, что первое продолжается. Я бы скопировал Gishu и написал что-то вроде (извините, если есть некоторые ошибки):

for( int idx = 0; idx < vectorLength; idx++) {
    if( !conditionAtVectorPosition( v, idx ) && CheckedEntireMatrix(v))
        setValueInVector( v, idx );
}

inline bool CheckedEntireMatrix(Vector v) {
    for(rowIdx = 0; rowIdx < n; rowIdx++)
        if ( !anotherConditionAtVector(v,rowIdx) && conditionAtMatrixRowCol(m,rowIdx,idx) ) 
            return false;
    return true;
}

Ответ 12

@Сэди:

Все они выглядят менее читабельными, чем оригиналы, поскольку они требуют большего количества кода для механизма кода, а не самого алгоритма

Внешнее включение второго цикла вне алгоритма не обязательно менее читаемо. Если имя метода выбрано хорошо, оно может улучшить читаемость.

Некоторые из них сломаны или были до того, как они были отредактированы. Большинство проклятий - это тот факт, что людям приходится много думать о том, как писать код без ярлыков и ничего не сломать.

У меня другая точка зрения: некоторые из них разбиты, потому что трудно понять поведение исходного алгоритма.

Некоторые из них имеют ограничение производительности за выполнение одного и того же теста дважды, что может не всегда быть тривиальным. Альтернативой этому является сохранение и прохождение вокруг булевых элементов, которое становится уродливым.

Снижение производительности незначительно. Однако я согласен, что выполнение теста дважды не является хорошим решением.

Рефакторинг соответствующей части кода в метод фактически не работает: он реорганизует, как код выложен в файле, но не влияет на его выполнение.

Я не вижу смысла. Да, это не изменяет поведение, например... рефакторинг?

Конечно, есть случаи, когда метки используются некорректно и должны быть удалены. Я просто не думаю, что это должно рассматриваться как какое-то нерушимое правило.

Я полностью согласен. Но, как вы уже указали, некоторые из нас испытывают трудности при рефакторинге этого примера. Даже если исходный пример доступен для чтения, его трудно поддерживать.