所以我在字符串上执行一些mod算术类型的东西,其中每个char获得一个特定的初始值(在其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);
}
编辑****回应David Wallace的回答
对不起,我重读了你的解释,我明白你在做什么......你的回答正是我所得到的。我只是在处理字符是一个数字的情况下遇到麻烦,因为它只添加数值而不是乘以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);
}
答案 0 :(得分:0)
如果结果:
long longVal = new BigInteger(stringVal).mod(new BigInteger(modulus)).longValue();
太大而不适合long
您会遇到以下行为,引用JDK中的BigInteger#longValue方法:
如果这个BigInteger太大而不适合长,只返回低位64位。请注意,此转换可能会丢失有关BigInteger值的总体大小的信息,并返回具有相反符号的结果。
因此,如果您尝试从long
大于BigInteger
获得long
值,那么您将无法获得准确的结果。
答案 1 :(得分:0)
如果您以某个模数执行此操作,则迭代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;
}