Как делают я нахожу миллионное число в ряду: 2 3 4 6 9 13 19 28 42 63 …?

Существует три основные причины.

  1. FacesServlet не вызывается.
  2. Недопустимые URI пространства имен XML.
  3. Несколько JSF были загружены.

1. Убедитесь, что URL-адрес соответствует FacesServlet mapping

. URL-адрес ссылки (URL-адрес, который вы видите в адресной строке браузера) должен соответствовать файла FacesServlet, как определено в web.xml чтобы все работы JSF выполнялись. FacesServlet - это тот, который отвечает за разбор файла XHTML, сбор представленных значений формы, выполнение преобразования / проверки, обновление моделей, вызывание действий и создание выходных данных HTML. Если вы не вызываете FacesServlet по URL-адресу, то все, что вы получили (и увидите через rightclick, View Source в браузере), действительно является исходным исходным кодом XHTML.

Если , например, *.jsf, ссылка должна указывать на /register.jsf, а не на /register.xhtml. Если это, например, /faces/*, как и у вас, ссылка должна указывать на /faces/register.xhtml, а не на /register.xhtml. Один из способов избежать этой путаницы - просто изменить с /faces/* на *.xhtml. Таким образом, нижестоящее является идеальным отображением:


    facesServlet
    javax.faces.webapp.FacesServlet


    facesServlet
    *.xhtml

Если вы по какой-то причине не можете поменять на *.xhtml, то вы, вероятно, также хотели бы, чтобы конечные пользователи не могли напрямую обращаться к источнику XHTML кодировать файлы по URL-адресу. В этом случае вы можете добавить в в *.xhtml с пустым в web.xml, который предотвращает это:


    Restrict direct access to XHTML files
    
        XHTML files
        *.xhtml
    
    
 

Предстоящий JSF 2.3 решит все из вышеперечисленного, автоматически регистрируя FacesServlet в шаблоне URL-адреса *.xhtml во время запуска webapp.

См. также:


2. Убедитесь, что пространства имен XML соответствуют версии JSF

. С введением JSF 2.2 еще одна вероятная причина заключается в том, что пространства имен XML не соответствуют версии JSF. xmlns.jcp.org, как показано ниже, является новым с JSF 2.2 и не работает в старых версиях JSF. Символы почти такие же, как если бы FacesServlet не вызывался.


Если вы не можете перейти на JSF 2.2, вам нужно вместо этого использовать старые пространства имен java.sun.com XML:


См. также:


3. Было загружено несколько реализаций JSF

. Еще одна вероятная причина заключается в том, что несколько реализаций JSF были загружены вашим webapp, конфликтуя и разлагая друг друга. Например, когда ваш путь к классу среды выполнения Webapp загрязнен несколькими различными версиями JSF-библиотек или в конкретной комбинации Mojarra 2.x + Tomcat 8.x, когда в файле web.xml веб-приложения есть ненужная запись ConfigureListener, вызывающая ее загрузку дважды.





    com.sun.faces.config.ConfigureListener

При использовании Maven убедитесь, что вы правильно определяете зависимости и понимаете области зависимостей. Важно: не связывайте зависимости в webapp, если они уже предоставлены целевым сервером.

См. Также:


Убедитесь, что вы учитесь JSF правильный путь

JSF имеет очень крутую кривую обучения для тех, кто не знаком с базовыми HTTP , HTML и сервлетами . В Интернете много ресурсов низкого качества. Пожалуйста, игнорируйте фрагменты скриншотов кода, поддерживаемые любителями, в основном ориентированные на доход от рекламы, а не на обучение, такие как розы, учебник, javabeat и т. Д. Они легко узнаваемы, нарушая рекламные ссылки / баннеры. Также, пожалуйста, игнорируйте ресурсы, связанные с юрским JSF 1.x. Они легко узнаваемы с помощью JSP-файлов вместо файлов XHTML. JSP как технология просмотра устарела с тех пор, как JSF 2.0 уже в 2009 году.

Чтобы начать правильно, начните с нашей вики-страницы JSF и закажите авторитетную книгу .

См. также:

27
задан 7 revs, 4 users 66% 15 May 2010 в 19:52
поделиться

12 ответов

Вы можете легко решить это, думая о проблеме в двоичном виде. Floor(3/2*i) - это, по сути, сдвиг вправо, усечение и сложение. В псевдокоде:

0b_n[0]   = 10              // the start is 2
0b_n[1]   = 10 + 1(0) = 11  // shift right, chop one bit off and add 
0b_n[i+1] = 0b_n[i] + Truncate(ShiftRight(0b_n[i]))

Это должно быть довольно быстро реализовано в любой форме.

Я только что сделал реализацию этого в системе Mathematica, и кажется, что операция BitShiftRight также отрезает бит после единичной позиции, так что об этом заботятся автоматически. Вот одна строка:

In[1] := Timing[num = Nest[(BitShiftRight[#] + #) &, 2, 999999];]
Out[2] = {16.6022, Null}

16 секунд, число печатается просто отлично, хотя оно довольно длинное:

In[2] := IntegerLength[num]
Out[2] = 176092

In[3] := num
Out[3] = 1963756...123087

Полный результат здесь.

19
ответ дан 28 November 2019 в 04:42
поделиться

Вы почти нашли это. В следующий раз ознакомьтесь с онлайн-энциклопедией целочисленных рядов .

Вот запись: http://oeis.org/A061418

     FORMULA    

a(n) = ceiling[K*(3/2)^n] where K=1.08151366859...

The constant K is 2/3*K(3) (see A083286). - Ralf Stephan, May 29, 2003 

Сказано:

>>> def f(n):
...     K = 1.08151366859
...     return int(ceil(K*(1.5)**n))

Тест на психическое здоровье:

>>> for x in range(1, 10):
...     print f(x)
...     
2
3
4
6
9
13
19
28
42

Круто! А как насчет 1000000:

>>> f(1000000)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 3, in f
OverflowError: (34, 'Result too large')

Ну, я попробовал. :] Но вы поняли идею.

Редактировать еще раз: Решение найдено! См. Тимо или Лассе В. Карлсен .

Редактировать: Используя идею смещения битов Тимо:

import gmpy
n=gmpy.mpz(2)
for _ in xrange(10**6-1):
    n+=n>>1
print(n)

дает

1963756763 ... 226123087 (176092 цифры)

% time test.py > test.out

real    0m21.735s
user    0m21.709s
sys 0m0.024s
13
ответ дан 10 revs, 3 users 75% 28 November 2019 в 04:42
поделиться

Я использовал следующую Java-программу:

import java.math.*;

public class Series {
    public static void main(String[] args) {
        BigInteger num = BigInteger.valueOf(2);
        final int N = 1000000;

        long t = System.currentTimeMillis();
        for (int i = 1; i < N; i++) {
            num = num.shiftLeft(1).add(num).shiftRight(1);
        }
        System.out.println(System.currentTimeMillis() - t);
        System.out.println(num);
    }
}

Обрезанный вывод: ( полный вывод на pastebin )

516380 (milliseconds)
196375676351034182442....29226123087

Так что потребовалось около 8,5 минут на моей скромной машинке. Я использовал -Xmx128M, но не уверен, действительно ли это было необходимо.

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

Пробные прогоны

6
ответ дан 6 revs 28 November 2019 в 04:42
поделиться

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

http://en.wikipedia.org/wiki/Recurrence_relation

Кроме того, не используйте bash.

1
ответ дан Joe 28 November 2019 в 04:42
поделиться

Причина того, что ваш скрипт такой медленный, заключается в том, что он запускается bc трижды, tr один раз и sed один раз в цикле.

Перепишите все это в bc и выполните sed в конце. Мой тест показывает, что версия, предназначенная только для bc , работает более чем в 600 раз быстрее. На старой медленной системе версии bc потребовалось чуть менее 16 минут, чтобы найти 100 000-е значение (распечатывая только последнее).

Также обратите внимание, что ваша функция «floor» на самом деле является int.

#!/usr/bin/bc -lq
define int(n) {
    auto oscale
    oscale = scale
    scale = 0
    n = n/1
    scale = oscale
    return n
}

define series(n) {
    return int(3/2*n)
}

n = 2
end = 1000
for (count = 1; count < end; count++ ) {
    n = series(n)
}
print count, "\t", n, "\n"
quit

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

Теперь вы можете выполнить chmod + x series.bc и называть его так:

./series.bc | tr -d '\n' | sed 's.\\..g'
11
ответ дан 28 November 2019 в 04:42
поделиться

Это идентифицируется как последовательность A061418 в сайте последовательностей (также известная как «Интернет-энциклопедия целочисленных последовательностей»); на соответствующую страницу ,

ФОРМУЛА a (n) = A061419 (n) +1 = потолок [K * (3/2) ^ n] где K = 1.08151366859 ... Константа K равна 2/3 * K (3) (см. A083286).

и с подходящей высокоточной библиотекой (GMP, как уже предлагалось, или MPIR, и, возможно, оболочка сверху, как мой ребенок gmpy для Python), вы можете использовать формулу закрытой формы для многих более быстрое вычисление «миллионной позиции в серии» и тому подобное.

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

2
ответ дан 28 November 2019 в 04:42
поделиться

Хм, bash не то, что я Буду использовать для высокоскоростной численной обработки. Получите себе копию GMP и соберите для этого программу на языке C.

Вполне возможно, что существует математическая формула, чтобы быстро ее дать, но за время, необходимое вам, чтобы это понять, GMP, вероятно, может выдать вам результат: -)

3
ответ дан 28 November 2019 в 04:42
поделиться

Вот версия на Python, которая на моем 10-летнем ноутбуке выполняется за 220 секунд:

import math;
import timeit;

def code():
  n = 2
  nth = 1

  while nth < 1000000:
    n = (n * 3) >> 1
    nth = nth + 1

  print(n);

t = timeit.Timer(setup="from __main__ import code", stmt="code()");
print(t.timeit(1));

Она дает тот же результат, что и этот ответ на pastebin (то есть я проверил начало и конец, а не все)

.
5
ответ дан 28 November 2019 в 04:42
поделиться

Рекурсивная формулировка займет довольно много времени при большинстве Curcumstances, потому что он должен поддерживать стек машины. Почему бы не использовать динамический программирование вместо этого?

т.е. (псевдокод)

bignum x = 2
for (int i = 1; i < 1000000; i++) {
    x = floor(3.0/2*x)
}

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

0
ответ дан 28 November 2019 в 04:42
поделиться

Я преобразовал идеи Тимо в elisp. Ошибка 100, что дает отрицательное число. FAIL, см. no BigNums !

(progn
  (let ((a 2)
        (dummy 0))
    (while (< dummy 100)
      (setq a (+ a (lsh a -1)))
      (setq dummy (1+ dummy)))
    (message "%d" a)))
-211190189 #WRONG evalution
0
ответ дан 28 November 2019 в 04:42
поделиться

Вы, вероятно, сможете приблизиться немного ближе, используя более подходящий язык, например, Схема:

(define (series n) (if (= n 0) 2
                       (quotient (* 3 (series (- n 1))) 2)))

Это вычисляет 17610 цифр (серия 100000) примерно за 8 секунд на моей машине. К сожалению, (series 1000000) все еще занимает слишком много времени, чтобы даже гораздо более новая / более быстрая машина имела хоть какую-то надежду закончить за минуту.

Переход на C ++ с библиотекой для больших целых чисел (в данном случае NTL):

#include <NTL/zz.h>
#include <fstream>
#include <time.h>
#include <iostream>

int main(int argc, char **argv) {
    NTL::ZZ sum;

    clock_t start = clock();
    for (int i=0; i<1000000; i++) 
        sum = (sum*3)/2;
    clock_t finish = clock();
    std::cout << "computation took: " << double(finish-start)/CLOCKS_PER_SEC << " seconds.\n";

    std::ofstream out("series_out.txt");
    out << sum;

    return 0;
}

Это вычисляет ряд для 1000000 за 4 минуты 35 секунд на моей машине. Этого достаточно, чтобы я мог почти поверить, что действительно быстрая новая машина может хотя бы приблизиться к завершению за минуту (и да, я проверил, что произошло, когда я использовал сдвиги вместо умножения / деления - это был медленнее).

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

2
ответ дан 28 November 2019 в 04:42
поделиться

Это очень просто сделать в Pari :

n=2;for(k=1,10^6,n+=n>>1)

Это займет 14 секунд на моей машине. Конечно, есть и более быстрые способы - на ум приходит GMP, - но зачем вообще? Вы не сможете сократить время выполнения более чем на 10 секунд, а время разработки будет порядка минут . :)

Второстепенный момент: в исходной формулировке неоднозначно, желателен ли миллионный член n 999999 или n 1000000 , число с индексом один миллион; Я даю последнее, так как вижу, что первое уже вычислено выше.

2
ответ дан 28 November 2019 в 04:42
поделиться
Другие вопросы по тегам:

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