Можно ли упростить этот алгоритм?

Научитесь настраивать и писать свои собственные теги с помощью JSTL

. Заметьте, что EL - это EviL (исключения времени выполнения, рефакторинг). Калитка также может быть злой (производительность, трудная для небольших приложений или простой уровень обзора). Пример из java2s ,

Это должно быть добавлено в веб-приложение web.xml

<taglib>
    <taglib-uri>/java2s</taglib-uri>
    <taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>

создать файл: java2s.tld в / WEB-INF /

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<!-- a tab library descriptor -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>Java2s Simple Tags</short-name>

    <!-- this tag manipulates its body content by converting it to upper case
    -->
    <tag>
        <name>bodyContentTag</name>
        <tag-class>com.java2s.BodyContentTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
          <name>howMany</name>
        </attribute>
    </tag>
</taglib>

скомпилировать следующий код в WEB-INF \ classes \ com \ java2s

package com.java2s;

import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyContentTag extends BodyTagSupport{
    private int iterations, howMany;

    public void setHowMany(int i){
        this.howMany = i;
    }

    public void setBodyContent(BodyContent bc){
        super.setBodyContent(bc);
        System.out.println("BodyContent = '" + bc.getString() + "'");
    }

    public int doAfterBody(){
        try{    
            BodyContent bodyContent = super.getBodyContent();
            String bodyString  = bodyContent.getString();
            JspWriter out = bodyContent.getEnclosingWriter();

            if ( iterations % 2 == 0 ) 
                out.print(bodyString.toLowerCase());
            else
                out.print(bodyString.toUpperCase());

            iterations++;
            bodyContent.clear(); // empty buffer for next evaluation
        }
        catch (IOException e) {
            System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage());
            e.printStackTrace();
        } // end of catch

        int retValue = SKIP_BODY;

        if ( iterations < howMany ) 
            retValue = EVAL_BODY_AGAIN;

        return retValue;
    }
}

Запустить сервер и загрузить bodyContent.jsp в браузере

<%@ taglib uri="/java2s" prefix="java2s" %>
<html>
    <head>
        <title>A custom tag: body content</title>
    </head>
    <body>
        This page uses a custom tag manipulates its body content.Here is its output:
        <ol>
            <java2s:bodyContentTag howMany="3">
            <li>java2s.com</li>
            </java2s:bodyContentTag>
        </ol>
    </body>
</html>
25
задан Steven A. Lowe 19 December 2008 в 19:15
поделиться

26 ответов

(a + p <= b) && (a != 1) && (b - a - p != 1);
37
ответ дан jjnguy 15 October 2019 в 15:06
поделиться
(((a+p) <= b) && (a == 0 || a > 1) && (b >= p)) && ((b - (a + p) == 0) || (b - (a + p) > 1))

с тех пор a> =0 (положительные целые числа), термин (== 0 || a> 1) всегда верен

если ((a+p) < = b) тогда (b> = p) верен, когда a, b, p> =0

поэтому ((a+p) < = b) & & (== 0 || a> 1) & & (b> = p)) & & ((b - (+ p) == 0), уменьшает до

b>=(a+p)

(b - (+ p) == 0) || (b - (+ p)>, 1) эквивалентно b> = (a+p)

поэтому, целое уравнение уменьшает до

**b>= (a+p)**
-1
ответ дан Matthew 15 October 2019 в 15:06
поделиться
b >= (a+p) && a>=1

даже b >= p избыточно, поскольку это будет всегда иметь место для a >= 1

0
ответ дан Jean-François Corbett 15 October 2019 в 15:06
поделиться

Первое повторение:

bool bool1 = ((a+p) <= b) && (a == 0 || a > 1) && (b >= p);
bool bool2 = (b - (a + p) == 0) || (b - (a + p) > 1);

return bool1 && bool2;

1111-секундное повторение:

int value1 = b - (a + p);
bool bool1 = (value1 >= 0) && (a == 0 || a > 1) && (b >= p);
bool bool2 = (value1 == 0) || (value1 > 1);

return bool1 && bool2;

Третье повторение (все положительные стороны)

int value1 = b - (a + p);
bool bool1 = (value1 >= 0) && (a != 1) && (b >= p);
bool bool2 = (value1 == 0) || (value1 > 1);

return bool1 && bool2;

4-е повторение (все положительные стороны)

int value2 = b - p;
int value1 = value2 - a;
bool bool1 = (value1 >= 0) && (a != 1) && (b - p >= 0);
bool bool2 = (value1 == 0) || (value1 > 1);

return bool1 && bool2;

5-е повторение:

int value2 = b - p;
int value1 = value2 - a;
bool bool1 = (value1 >= 0) && (a != 1) && (value2 >= 0);
bool bool2 = (value1 == 0) || (value1 > 1);

return bool1 && bool2;
0
ответ дан Tamara Wijsman 15 October 2019 в 15:06
поделиться

Я чувствую (a! = 1) & & (+ p < = b) & & (+ p! = b - 1) немного более ясно. Другая опция:

интервал t = b-p; (a! = 1 & & < = t & & a! = t-1)

В основном или 0, t, или находится между 2 и t-2 включительно.

0
ответ дан amit 15 October 2019 в 15:06
поделиться

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

, Так как нам сказали принять a> = 0, и первое условие гарантирует, что b - (+ p)> = 0, на кронштейнах || тесты могут быть превращены в тесты против неравенства с 1:

(+ p < = b) & & (a! = 1) & & (b> = p) & & (b - p! = 1)

заманчиво удалить проверку (b> = p), который дал бы выражение nickf. И это - почти наверняка корректное практическое решение. К сожалению, мы должны знать больше о проблемной области перед способностью сказать, безопасно ли сделать это.

, Например, при использовании C и 32-разрядный неподписанный ints для типов a, b, и p, рассматривают случай где = 2^31 + 7, p = 2^31 + 5, b = 13. У нас есть a> 0, (+ p) = 12 < b, но b < p. (Я использую '^' для указания на возведение в степень, не C поразрядный xor.)

, Вероятно, Ваши значения не приблизятся к виду диапазонов, где этот вид переполнения является проблемой, но необходимо проверить это предположение. И если это оказывается возможностью, добавьте комментарий с тем выражением, объяснив это так, чтобы некоторый рьяный будущий оптимизатор небрежно не удалял (b> = p) тест.

0
ответ дан 15 October 2019 в 15:06
поделиться

(((a+p) < = b) & & (== 0 || a> 1) & & (b> = p)) & & ((b - (+ p) == 0) || (b - (+ p)> 1))

1) (== 0 || a> 1) (a! = 1)

2) (b> = p) (b - p> = 0)

(+ p < = b) (b - p> = a), который более силен, чем (b - p> = 0).

Первое условие уменьшило до [1 112] (a! = 1) & & (b - p> = a).

3) (b - (+ p) == 0) (b - p == 0), (b - p == a).

(b - (+ p)> 1) (b - p> 1) (b - p> 1 + a).

, Так как мы имели (b - p> = a) и мы используем & & операция, мы можем сказать что (b - p> = покрытия a) (b - p == & & b - p> 1 + a).

Следовательно, целое условие будет уменьшено до

(a! = 1 & & (b - p> = a))

существует tempation для сокращения его далее до (b> = p), но это сокращение не покроет запрет на b = p + 1, поэтому (a! = 1 & & (b - p> = a)), условие.

0
ответ дан wasker 15 October 2019 в 15:06
поделиться

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

// Initial equation
(((a + p) <= b) && (a == 0 || a > 1) && (b >= p)) && ((b - (a + p) == 0) || (b - (a + p) > 1))

// ((a + p) <= b) iif a = 0 && p = b; therefore, b = p and a = 0 for this to work
(b == p) && ((b - (a + p) == 0) || (b - (a + p) > 1))

// Simplification, assuming that b = p and a = 0
(b == p) && (a == 0)

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

(a == 0 || a > 1)

только оценил бы к истинному когда a> = 2; однако, если следующее также верно:

(b >= p)

Тогда это означает, что p, по крайней мере, равен b, таким образом:

((a + p) <= b)

заменой становится:

((2 + b) <= b)

, Который никогда не может ясно оценивать к истинному.

0
ответ дан rjzii 15 October 2019 в 15:06
поделиться

как о следующей логике, прокомментируйте его:

((a == 0 || a > 1) && ((b-p) > 1) )
0
ответ дан 15 October 2019 в 15:06
поделиться

Если a, b и p являются положительными целыми числами (предполагающий, что положительный диапазон включает эти 0 значений) тогда выражение (((a+p) < = b) & & (== 0 || a> 1) & & (b> = p)) & & ((b - (+ p) == 0), || (b - (+ p)> 1)) может быть уменьшен до ((a+p) < =b) & & (a! =1) & & ((b-(a+p))! =1)

Позволяют мне продемонстрировать его: В первой части выражения существует условие, ((a+p) < =b) , что, если оценено истинный рендеринг, верный вторая часть: ((b - (+ p) == 0) || (b - (+ p)> 1)) . Если это верно, что (b> = (a+p)) тогда (b - (a+p)) должны быть больше или равными 0 , мы должны гарантировать что (b-(a+p))! =1 . Отложите этот термин некоторое время и продолжите.

Теперь мы можем сконцентрировать наши усилия на первая часть (((a+p) < = b) & & (== 0 || a> 1) & & (b> = p)) & & ((b-(a+p))! =1)

, Если положительно тогда, что это всегда> =0 и таким образом, мы можем отбросить тест (== 0 || a> 1) если польза (a! =1), и уменьшают первую часть выражения к [1 117] (((a+p) < = b) & & (b> = p) & & (a! =1)) .

Для следующего шага сокращения можно полагать, что, если b> = (a+p) тогда, очевидно b> =p ( положительно) и выражение могут быть уменьшены до

((a+p) < =b) & & (a! =1) & & ((b-(a+p))! =1)

0
ответ дан Eineki 15 October 2019 в 15:06
поделиться

Я добавил это как комментарий к ответу nickf, но думал, что предложу его как ответ на своем собственном. Хорошие ответы все, кажется, изменение его, включая мой. Но так как мы не в зависимости от компилятора для оптимизации (если бы OP были, мы даже не сделали бы этого), тогда кипятящий это по сравнению с 3 ANDs к следующим средствам, что будут значения, где только 2 из этих 3 частей должны будут быть оценены. И если бы это делается в сценарии, это имело бы значение в противоположность скомпилированному коду.

(a != 1) && ((b > (a + p + 1)) || (b == (a + p))))

На основе комментария, я собираюсь добавить этот wrt этот являющийся лучше, чем И версия:

я предполагаю, что это зависит от того, больше ли Ваш истинный набор данных результатов, чем 50 процентов входных наборов. Чем чаще вход верен, тем лучше мое изменение будет. Так, с этим уравнением это похоже, И стиль будет лучше (по крайней мере, для моего набора входных данных 0-500).

0
ответ дан shank 15 October 2019 в 15:06
поделиться

Хорошо

((b - (a + p) == 0) || (b - (a + p) > 1))

Would be better writen as:
(b - (a + p) >= 0)  

Applying this to the whole string you get:

((a+p) <= b) && (a > 1) && (b >= p)) && (b - (a + p) >= 0) 


(a + p) <= b is the same thing as b - (a + p) >= 0

, Таким образом, можно избавиться от того отъезда:

((a+p) <= b) && (a > 1) && (b >= p)) 
0
ответ дан jjnguy 15 October 2019 в 15:06
поделиться
// In one line:
return (a != 1) && ((b-a-p == 0) || (b-a-p > 1))

// Expanded for the compiler:
if(a == 1)
    return false;

int bap = b - a - p;

return (bap == 0) || (bap > 1);

при регистрации процессора Вы используете, я могу оптимизировать для блока. =]

1
ответ дан strager 15 October 2019 в 15:06
поделиться

Это столь просто, как я мог получить его.

def calc(a, b, p):
    if (a != 1):
        temp = a - b + p
        if temp == 0 or temp < -1:
            return True
    return False

Это могло также быть записано как:

def calc(a, b, p):
    temp = a - b + p
    return a != 1 and (temp == 0 or temp < -1)

Или как:

def calc(a, b, p):
    temp = a - b + p
    return a != 1 and temp <= 0 and temp != -1
1
ответ дан Kristof Neirynck 15 October 2019 в 15:06
поделиться

Протестированный с a, b, p от 0 до 10 000:

a != 1 && a != (b-p-1) && a <= (b-p);

я думаю, что это может быть упрощено еще больше.

1
ответ дан csl 15 October 2019 в 15:06
поделиться
bap = b - (a + p)
bap >= 0 && bap != 1 && a != 1

РЕДАКТИРОВАНИЕ: Теперь я имею-2 для честной попытки выручения и также для того, что, кажется, мне действительный ответ. Для Вас, кто может использовать Python, вот две функции, один с вопросом и один с моим ответом:

def question(a, b, p):
    return (((a+p) <= b) and (a == 0 or a > 1) and (b >= p)) or ((b - (a + p) == 0) or (b - (a + p) > 1))

def answer(a, b, p):
    bap = b - (a + p)
    return bap >= 0 and bap != 1 and a != 1
1
ответ дан PEZ 15 October 2019 в 15:06
поделиться
s = a + p
b >= s && a != 1 && b - s - 1 > 0

Проверено, возвращает то же логическое значение, что и вопрос.

Программа, которую я использовал для проверки: (весело писал ее)

#include <iostream>
using namespace std;

typedef unsigned int uint;

bool condition(uint a, uint b, uint p)
{
        uint s = a + p;
        return uint(    b >= s && a != 1 && b - s - 1 > 0    )
        == uint(    (((a+p) <= b) && (a == 0 || a > 1) && (b >= p))
                 && ((b - (a + p) == 0) || (b - (a + p) > 1))    );
}

void main()
{
    uint i = 0;
    uint j = 0;
    uint k = 0;

    const uint max = 50;

    for (uint i = 0; i <= max; ++i)
        for (uint j = 0; j <= max; ++j)
            for (uint k = 0; k <= max; ++k)
                if (condition(i, j, k) == false)
                {
                    cout << "Fails on a = " << i << ", b = " << j;
                    cout << ", p = " << k << endl;

                    int wait = 0;
                    cin >> wait;
                }
}
1
ответ дан Tamara Wijsman 15 October 2019 в 15:06
поделиться

Так как ints не подписаны, (== 0 || a> 1) может быть заменен (a! =1).

С первой передачей, можно уменьшить его до этого:

uint sum = a + p;
return ((sum <= b) && (a != 1) && (b >= p)) && (b - sum != 1);

кроме того, это было бы намного более читаемо, если бы Вы смогли дать больше понятных имен переменным. Например, если бы a и p были давлениями, то a+p мог быть substitued как PressureSum.

1
ответ дан Brian Genisio 15 October 2019 в 15:06
поделиться

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

Таким образом, в качестве первого шага

(((a+p) <= b) && (a == 0 || a > 1) && (b >= p)) && ((b - (a + p) == 0) || (b - (a + p) > 1))

становится

((a+p) <= b) && (a != 1) && (b >= p)) && ((b - (a + p) != 1) 

Для для ясности, это просто замена паттерна (foo == 0 || foo > 1) на foo != 1

Этот паттерн появляется дважды выше, один раз с foo = a и один раз с foo = (b - (a+p))

2
ответ дан jjnguy 15 October 2019 в 15:06
поделиться

Я не сделал бы всей математики в том выражении. Такой, поскольку b - (+ p) оценен дважды. Если возможно, разделяет их на переменные вместо этого.

кроме того, пишущий полировку notiation дерево мог бы помочь Вам оптимизировать его, все, что Вы видите дважды, может быть снова использован.

2
ответ дан Filip Ekberg 15 October 2019 в 15:06
поделиться
(a!=1) && ((b==a+p) || (b>1+a+p))

Это может быть не самое простое, но должно быть одним из самых читаемых.

4
ответ дан Dennis C 15 October 2019 в 15:06
поделиться
b >= p && b != p+1

РЕДАКТИРОВАНИЕ: хорошо, который не работал, но этот делает:

a != 1 && b >= a+p && b-a-p != 1
4
ответ дан Can Berk Güder 15 October 2019 в 15:06
поделиться

Рефакторинг для простоты, введя больше локальных переменных, которые указывают значение каждого выражения. Это трудно для нас, не имея представления о том, что означают a, b и p.

5
ответ дан Jon Skeet 15 October 2019 в 15:06
поделиться

Если формула работает, и произойдите из своих бизнес-правил нет никакой реальной потребности упростить ее. Компилятор, вероятно, знает лучше, чем мы как к оптимизации формулы.

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

Остерегаются применения любого предлагаемого решения перед поблочным тестированием их.

16
ответ дан Andrea Francia 15 October 2019 в 15:06
поделиться

jjngy здесь имеет его правильный. Вот доказательство, что его упрощенная формула эквивалентна исходному использованию Помощник Доказательства Coq .

Require Import Arith.
Require Import Omega.

Lemma eq : forall (a b p:nat),
(((a+p) <= b) /\ ((a = 0) \/ (a > 1)) /\ (b >= p)) /\ 
    ((b - (a + p) = 0) \/ (b - (a + p) > 1)) <-> 
((a + p <= b) /\ ~ (a= 1) /\ ~ (b - a - p = 1)).
Proof. intros; omega. Qed.
1
ответ дан huitseeker 15 October 2019 в 15:06
поделиться

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

исправленная деривация следует, в форме тестовой программы.

Короткий ответ:

((a > 1) && (skeet == 0)) || ((a > 1) && (jon > 0) && (skeet < -1));

где

jon = (b - p)
skeet = (a - jon);

class Program
{
    static void Main(string[] args)
    {
        bool ok = true;
        for (int a = 1; a < 100; a++)
        {
            Console.Write(a.ToString());
            Console.Write("...");

            for (int b = 1; b < 100; b++)
            {
                for (int p = 1; p < 100; p++)
                {
                    bool[] results = testFunctions(a, b, p);
                    if (!allSame(results))
                    {
                        Console.WriteLine(string.Format(
                            "Fails for {0},{1},{2}", a, b, p));
                        for (int i = 1; i <= results.Length; i++)
                        {
                            Console.WriteLine(i.ToString() + ": " + 
                                results[i-1].ToString());
                        }

                        ok = false;
                        break;
                    }
                }
                if (!ok) { break; }
            }
            if (!ok) { break; }
        }
        if (ok) { Console.WriteLine("Success"); }
        else { Console.WriteLine("Failed!"); }
        Console.ReadKey();
    }

    public static bool allSame(bool[] vals)
    {
        bool firstValue = vals[0];
        for (int i = 1; i < vals.Length; i++)
        {
            if (vals[i] != firstValue)
            {
                return false;
            }
        }
        return true;
    }

    public static bool[] testFunctions(int a, int b, int p)
    {
        bool [] results = new bool[16];

        //given: all values are positive integers
        if (a<=0 || b<=0 || p<=0)
        {
            throw new Exception("All inputs must be positive integers!");
        }

        //[1] original expression
        results[0] = (((a+p) <= b) && (a == 0 || a > 1) && (b >= p)) && 
            ((b - (a + p) == 0) || (b - (a + p) > 1));

        //[2] a==0 cannot be true since a is a positive integer
        results[1] = (((a+p) <= b) && (a > 1) && (b >= p)) && 
            ((b - (a + p) == 0) || (b - (a + p) > 1));

        //[3] rewrite (b >= p) && ((a+p) <= b) 
        results[2] = (b >= p) && (b >= (a+p)) && (a > 1) && 
            ((b - (a + p) == 0) || (b - (a + p) > 1));

        //[4] since a is positive, (b>=p) guarantees (b>=(p+a)) so we 
        //can drop the latter term
        results[3] = (b >= p) && (a > 1) && 
            ((b - (a + p) == 0) || (b - (a + p) > 1));

        //[5] separate the two cases b>=p and b=p
        results[4] = ((b==p) && (a > 1) && ((b - (a + p) == 0) || 
            (b - (a + p) > 1))) || ((b > p) && (a > 1) && 
            ((b - (a + p) == 0) || (b - (a + p) > 1)));

        //[6] rewrite the first case to eliminate p (since b=p 
        //in that case)
        results[5] = ((b==p) && (a > 1) && ((-a == 0) || 
            (-a > 1))) || ((b > p) && (a > 1) && 
            (((b - a - p) == 0) || ((b - a - p) > 1)));

        //[7] since a>0, neither (-a=0) nor (-a>1) can be true, 
        //so the case when b=p is always false
        results[6] = (b > p) && (a > 1) && (((b - a - p) == 0) || 
            ((b - a - p) > 1));

        //[8] rewrite (b>p) as ((b-p)>0) and reorder the subtractions
        results[7] = ((b - p) > 0) && (a > 1) && (((b - p - a) == 0) || 
            ((b - p - a) > 1));

        //[9] define (b - p) as N temporarily
        int N = (b - p);
        results[8] = (N > 0) && (a > 1) && (((N - a) == 0) || ((N - a) > 1));

        //[10] rewrite the disjunction to isolate a
        results[9] = (N > 0) && (a > 1) && ((a == N) || (a < (N - 1)));

        //[11] expand the disjunction
        results[10] = ((N > 0) && (a > 1) && (a == N)) ||
            ((N > 0) && (a > 1) && (a < (N - 1)));

        //[12] since (a = N) in the first subexpression we can simplify to
        results[11] = ((a == N) && (a > 1)) || 
            ((N > 0) && (a > 1) && (a < (N - 1)));

        //[13] extract common term (a > 1) and replace N with (b - p)
        results[12] = (a > 1) && ((a == (b - p)) || 
            (((b - p) > 0) && (a < (b - p - 1))));

        //[14] extract common term (a > 1) and replace N with (b - p)
        results[13] = (a > 1) && (((a - b + p) == 0) || 
            (((b - p) > 0) && ((a - b + p) < -1)));

        //[15] replace redundant subterms with intermediate 
        //variables (to make Jon Skeet happy)
        int jon = (b - p);
        int skeet = (a - jon);   //(a - b + p) = (a - (b - p))
        results[14] = (a > 1) && ((skeet == 0) || 
            ((jon > 0) && (skeet < -1)));

        //[16] rewrite in disjunctive normal form
        results[15] = ((a > 1) && (skeet == 0)) || 
            ((a > 1) && (jon > 0) && (skeet < -1));

        return results;
    }
}
1
ответ дан Steven A. Lowe 28 November 2019 в 17:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: