Super Pow--C++ Clean and Short Solution

关于Leetcode中的Super Pow 一题有几种不同的解法,在Leetcode的discuss板块中,我发现了一种很棒的解题思路,顺便翻译一下(加深记忆)。

作者:fentoyal
地址:C++ Clean and Short Solution

翻译如下

同余模定理: ab%k=(a%k)(b%k)%k

由于幂存放在数组中,我们最好将它一位一位的处理。

通过观察可知:(其实为了便于理解可以先将取模的过程去掉,这里保留原式子)
a1234567%k=(a1234560%k)(a7%k)%k=(a123456%k)10%k(a7%k)%k

看起来有点复杂?让我们采取另一种表达方式:
假设 f(a,b) 表示计算 ab%k 然后利用该函数表示上面的公式:
f(a,1234567)=f(a,1234560)f(a,7)%k=f(f(a,123456),10)f(a,7)%k

代码实现如下:

class Solution {
    const int base = 1337;
    int powmod(int a, int k) //a^k mod 1337 where 0 <= k <= 10
    {
        a %= base;
        int result = 1;
        for (int i = 0; i < k; ++i)
            result = (result * a) % base;
        return result;
    }
public:
    int superPow(int a, vector<int>& b) {
        if (b.empty()) return 1;
        int last_digit = b.back();
        b.pop_back();
        return powmod(superPow(a, b), 10) * powmod(a, last_digit) % base;
    }
};

Note: 这种方法显然不是最快的,但是当我们在面试中被问到这个问题时可以很快的理解并写出。还有这个方法没有使用内建的pow函数,我想这也是面试官所期待的。
希望它对你有帮助!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 C++ 实现的 RSA-3072 算法示例代码: ```c++ #include <iostream> #include <string> #include <cstdlib> #include <ctime> #include <cmath> using namespace std; string decimalToBinary(long long decimal) { string binary = ""; while(decimal != 0) { binary = to_string(decimal % 2) + binary; decimal /= 2; } return binary; } long long binaryToDecimal(string binary) { long long decimal = 0; for(int i = binary.length() - 1; i >= 0; i--) { if(binary[i] == '1') { decimal += pow(2, binary.length() - 1 - i); } } return decimal; } long long fastPower(long long base, long long exponent, long long mod) { long long result = 1; while(exponent != 0) { if(exponent % 2 == 1) { result = (result * base) % mod; } base = (base * base) % mod; exponent /= 2; } return result; } bool isPrime(long long n, int k) { if(n == 2 || n == 3) { return true; } if(n == 1 || n % 2 == 0) { return false; } long long d = n - 1; int s = 0; while(d % 2 == 0) { s++; d /= 2; } for(int i = 0; i < k; i++) { long long a = rand() % (n - 3) + 2; long long x = fastPower(a, d, n); if(x == 1 || x == n - 1) { continue; } for(int j = 0; j < s - 1; j++) { x = (x * x) % n; if(x == 1) { return false; } if(x == n - 1) { break; } } if(x != n - 1) { return false; } } return true; } long long generatePrimeNumber(int bits) { long long min = pow(2, bits - 1); long long max = pow(2, bits) - 1; long long p; do { p = rand() % (max - min + 1) + min; } while(!isPrime(p, 10)); return p; } long long gcd(long long a, long long b) { while(b != 0) { long long r = a % b; a = b; b = r; } return a; } void generateKeys(long long& p, long long& q, long long& n, long long& e, long long& d) { srand(time(NULL)); p = generatePrimeNumber(1536); q = generatePrimeNumber(1536); n = p * q; long long phi = (p - 1) * (q - 1); do { e = rand() % (phi - 2) + 2; } while(gcd(e, phi) != 1); long long k = 1; while((k * phi + 1) % e != 0) { k++; } d = (k * phi + 1) / e; } string encrypt(string message, long long e, long long n) { string binary = ""; for(int i = 0; i < message.length(); i++) { binary += decimalToBinary((int) message[i]); } while(binary.length() % 3072 != 0) { binary += "0"; } string ciphertext = ""; for(int i = 0; i < binary.length(); i += 3072) { string block = binary.substr(i, 3072); long long x = binaryToDecimal(block); long long y = fastPower(x, e, n); string cypherblock = decimalToBinary(y); while(cypherblock.length() < 6176) { cypherblock = "0" + cypherblock; } ciphertext += cypherblock; } return ciphertext; } string decrypt(string ciphertext, long long d, long long n) { string message = ""; for(int i = 0; i < ciphertext.length(); i += 6176) { string block = ciphertext.substr(i, 6176); long long y = binaryToDecimal(block); long long x = fastPower(y, d, n); string plaintextblock = ""; while(x != 0) { plaintextblock = to_string(x % 256) + plaintextblock; x /= 256; } while(plaintextblock.length() < 24) { plaintextblock = "0" + plaintextblock; } message += plaintextblock; } return message; } int main() { long long p, q, n, e, d; generateKeys(p, q, n, e, d); string message; cout << "Enter the message to be encrypted: "; getline(cin, message); string ciphertext = encrypt(message, e, n); cout << "Ciphertext: " << ciphertext << endl; string plaintext = decrypt(ciphertext, d, n); cout << "Plaintext: " << plaintext << endl; return 0; } ``` 这个示例代码实现了 RSA-3072 算法的密钥生成、加密和解密,其 `generatePrimeNumber` 函数生成指定位数的质数,`generateKeys` 函数生成公钥和私钥,`encrypt` 函数将明文转换为二进制并加密,`decrypt` 函数对密文解密并转换为明文。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值