Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Perl到Java_Java_Perl - Fatal编程技术网

从Perl到Java

从Perl到Java,java,perl,Java,Perl,我试图解决一些在线难题,找到一个非常大的数的最大素因子(确切地说是739391333591914005052111110339491123405991919445111971)。在寻找解决方案的过程中,我偶然发现了以下Perl代码(): 但是我的结果总是不正确。。。而我的Perl对于对原始代码进行反向工程并不是很好。有人知道我遗漏了什么吗 ==更新:问题通过解决方法(在某种程度上)解决了来回答翻译问题。。。 您的Java翻译非常接近。它只有一个问题-您的while循环条件应该是=0,而不是>0。

我试图解决一些在线难题,找到一个非常大的数的最大素因子(确切地说是739391333591914005052111110339491123405991919445111971)。在寻找解决方案的过程中,我偶然发现了以下Perl代码():

但是我的结果总是不正确。。。而我的Perl对于对原始代码进行反向工程并不是很好。有人知道我遗漏了什么吗

==更新:问题通过解决方法(在某种程度上)解决了

来回答翻译问题。。。 您的Java翻译非常接近。它只有一个问题-您的
while
循环条件应该是
=0
,而不是
>0
。有了这项修正案,它将起作用。事实上,在某些情况下,它将输出第二大素因子

要显示这一点,请尝试使用
1148487369611039
,它具有基本因子
104717
104723
104729
。没有校正-它输出
104723
,校正后,您会得到正确的答案:
104729

算法评述 正如其他人在评论中所指出的,这不是一种特别快速的方式来做你想做的事情。事实上,这是一种轻描淡写的说法——它非常缓慢。在我的盒子里,找到正确答案花了3分钟(
459905301806642105202622615174502491
)1,但要证明这个数是素数需要很长的时间(可能是500年,或者类似的顺序),只需简单地将每个奇数除以其平方根(这就是算法所做的)

你可以使用各种各样的技巧来加快速度,这取决于你对得到答案的把握程度。一种方法是预先测试任何候选素数-例如,使用
biginger.isProbablePrime()
作为
goAtIt()
中的测试插入一个测试,并在过程早期得到一个非常大的素数时提前返回。如果你不喜欢其中的概率因素,你可以自己动手。您还可以构建素数表,并且只能在任何试验划分和/或查找中使用这些素数表。你也可以考虑

1(我在
while
循环
goAtIt()
中的
之后放置了一个输出,以检查它何时实际找到了解决方案)

关于Perl大数的注记 Perl的一个小问题是它不接受真正大的数字

我认为它比这更糟糕,因为如果您简单地替换

my $magic = <number>;

因此,它会给出错误的答案,而不是像上面演示的那样抛出错误。这相当令人讨厌,因为该算法适用于较小的数字,如果与较大的输入一起使用,可能会使粗心的用户产生错误的安全感…

尽管这并不是您问题的答案:IMHO,您最好搜索其他素数分解算法,而不是尝试将此算法从Perl移植到Java。我想,对于这么大的数字来说,直接因子分解太慢了。作为一个提示:您是否也用较小的数字测试了重写的代码?如果它能工作,那么将数字增加,比如说,十次方左右,你就会看到计算是如何变慢的。perl代码使用浮点数,因此代码可能存在截断问题。您可能需要通过biginger.ONE在这里和那里轻推一个值。但这也没有真正起作用:-)我实际上觉得自己很愚蠢,我以前没有想到要寻找一个java示例来实现这一点。实际上,在stackoverflow上找到类似的解决方案并不难:。。。很抱歉,与使用递归相比,一种更快、占用内存更少的方法是,首先构建一个包含所有质数的列表,直到所讨论的数字。然后从大的数字开始倒转,寻找第一个等分的数字。
my $magic = <number>;
my $magic = Math::BigInt->new(' <number> ');
static final BigInteger two = new BigInteger( "2" );

public static void main( String[] args ) {
    BigInteger number = new BigInteger( "<number>" );

    System.out.println( goAtIt( number ) );
}

static BigInteger goAtIt( BigInteger prime ) {
    if ( isEven( prime ) )
        return goAtIt( prime.divide( two ).max( two ) );

    BigInteger sqrt = sqrt( prime );
    BigInteger comp = new BigInteger( "3" );

    while (sqrt.compareTo( comp ) > 0) {
        if ( prime.remainder( comp ).equals( BigInteger.ZERO ) )
            break;
        comp = comp.add( two );
    }

    if ( comp.compareTo( sqrt ) > 0 )
        return prime;

    return comp.max( goAtIt( prime.divide( comp ) ) );
}
static boolean isEven( BigInteger number ) {
    return number.getLowestSetBit() != 0;
}

static BigInteger sqrt( BigInteger n ) {
    BigInteger a = BigInteger.ONE;
    BigInteger b = new BigInteger( n.shiftRight( 5 ).add( new BigInteger( "8" ) ).toString() );
    while (b.compareTo( a ) >= 0) {
        BigInteger mid = new BigInteger( a.add( b ).shiftRight( 1 ).toString() );
        if ( mid.multiply( mid ).compareTo( n ) > 0 )
            b = mid.subtract( BigInteger.ONE );
        else
            a = mid.add( BigInteger.ONE );
    }
    return a.subtract( BigInteger.ONE );
}
my $magic = <number>;
my $magic = 7393913335919140050521110339491123405991919445111971;