我在一个字符串上执行一些mod算术类型的东西,其中每个字符都有一个特定的初始值(取决于它的ascii)和在字符串中的位置。这些数字由于其初始值为(ascii)*26^charPos而变得很大。值得注意的是,数字字符只会将其值(0-9)加到总数中;

有没有一种避免使用BigInt类的方法(因为我只对(intialVal)%(relatively small number))感兴趣,我想您可以使用通常的方法:

value += val;
  if(value >= mod)
   value = value % mod;


但这仅适用于整数排序列表,也无法解决使用上述字符值公式将单个字符生成BigInt的问题。我确信可以使用mod运算符来完成某些事情。

作为旁白;
如果bigNum超过long(或int,无论foo是什么声明)的大小,该算法将无法正确执行?

int(or long) foo = BigNum(possibly bigger than long) % smallMod;


我意识到我可以声明几个BigInteger对象,然后将所有值添加到totalValue中,然后对总数执行最终的mod操作,但我宁愿避免这种情况,因为BigInteger算法是我用得很少的(而且似乎很痛苦,在这种情况下通常是不必要的)。我知道会有很多方法,但是我不介意听到一些不同的观点。提前致谢。

这是我想出的一些代码,只要长阈值没有被破坏,它就会起作用。

public static void main(String[] args) {

    String str = "st4ck0ver";

    char[] x = str.toCharArray();
    long value = 0;
    int mod = 87;

    for(int i = 0; i < x.length; i++) {

        long val;
        int charVal;
        int exp = x.length - (i+1);

        if((int)x[i] < 58) {
            charVal = (int)x[i] - 48;
            val = charVal;
        }
        else{
            charVal = (int)x[i]- 96;
            val = (long) (charVal * Math.pow(26, exp));
        }

        value += val;

        System.out.println("exp:" + exp + ",  char:" + x[i] + ", "
                + ",  charValue:" + charVal + " value:" + val + ",  curr total value:" + value);
    }
    value %= mod;
    System.out.println("Final value:" + value);
}




编辑:回应大卫·华莱士的答案:

抱歉,我重新阅读了您的说明,并且我确实了解您的操作...您的回答恰恰是我的意思。我只是在处理字符是数字的情况时遇到麻烦,因为它仅添加数值而不是将其乘以26^pos。为了将其添加到最终答案中,我保留了数值的总计(以及在超出mod值时再次对其进行修改),但是我不知道如何将适当的功效增加一好。我可能缺少一些显而易见的东西。注释后的代码是我为解决此问题所做的一半尝试:

public static void main(String[] args) {
    //String str = "st4ck0ver";
    //String str = "hello";
    String str = "time2go";

    char[] x = str.toCharArray();
    int mod = 2004;

    int answer = 0;
    int power = 1;
    int numericalVal = 0;
    //int skipPower;

    for (int i = x.length - 1; i >=0; i--) {
        int charVal;

        if((int)x[i] < 58)  {
            charVal = (int)x[i] - 48;
            numericalVal += charVal;
            //skipPower++; //perhaps need to use something like this?
                //
        }       //      down
        else {  //   in here somewhere
            charVal = (int)x[i]- 96;

            answer += ( charVal * power);
            answer %= mod;
            power *= 26;
            power %= mod;
            //skipPower = 0; //reset skipPower in case it was used
        }
    }
    //answer += numericalVal;
    //if(answer + numericalVal >= mod)
    //  answer %= mod;

    System.out.println("Final value:" + answer);
}

最佳答案

如果您以特定的模数执行此操作,请遍历String,并跟踪该模数中所需值的连续总计,以及该模数中适当的26的幂的值。如您所言,如果模量非常小,则int对于其中的每一个都应足够。

请注意,我假设您的String在这里仅包含小写字母。如果需要,请对此进行修复。

int answer = 0;
int power = 1;

for (int i = 0; i < inputString.length(); i++) {
    int charValue = inputString.charAt(i) - 'a';
    answer += ( charValue * power );
    answer %= mod;
    power *= 26;
    power %= mod;
}


编辑

适应OP的编辑,该编辑显示必须以相反的顺序遍历String,并且在遇到数字时不考虑位置值,代码可能应如下所示。

int answer = 0;
int power = 1;

for (int i = inputString.length() - 1; i >=0; i--) {

    if(inputString.charAt( i ) < 58)  {
        int charValue  = inputString.charAt( i ) - 48;
        answer += charValue;
    }
    else {
        int charValue  = inputString.charAt( i ) - 96;
        answer += ( charValue * power );
    }

    answer %= mod;
    power *= 26;
    power %= mod;
}

关于java - 在算术中避免BigInteger类/大数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29248641/

10-12 00:31
查看更多