Task: Stirling numbers of the second kind


C++: #include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <gmpxx.h>

using integer = mpz_class;

class stirling2 {
public:
    integer get(int n, int k);
private:
    std::map<std::pair<int, int>, integer> cache_;
};

integer stirling2::get(int n, int k) {
    if (k == n)
        return 1;
    if (k == 0 || k > n)
        return 0;
    auto p = std::make_pair(n, k);
    auto i = cache_.find(p);
    if (i != cache_.end())
        return i->second;
    integer s = k * get(n - 1, k) + get(n - 1, k - 1);
    cache_.emplace(p, s);
    return s;
}

void print_stirling_numbers(stirling2& s2, int n) {
    std::cout << "Stirling numbers of the second kind:\nn/k";
    for (int j = 0; j <= n; ++j) {
        std::cout << std::setw(j == 0 ? 2 : 8) << j;
    }
    std::cout << '\n';
    for (int i = 0; i <= n; ++i) {
        std::cout << std::setw(2) << i << ' ';
        for (int j = 0; j <= i; ++j)
            std::cout << std::setw(j == 0 ? 2 : 8) << s2.get(i, j);
        std::cout << '\n';
    }
}

int main() {
    stirling2 s2;
    print_stirling_numbers(s2, 12);
    std::cout << "Maximum value of S2(n,k) where n == 100:\n";
    integer max = 0;
    for (int k = 0; k <= 100; ++k)
        max = std::max(max, s2.get(100, k));
    std::cout << max << '\n';
    return 0;
}




Java: import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

public class SterlingNumbersSecondKind {

    public static void main(String[] args) {
        System.out.println("Stirling numbers of the second kind:");
        int max = 12;
        System.out.printf("n/k");
        for ( int n = 0 ; n <= max ; n++ ) {
            System.out.printf("%10d", n);
        }
        System.out.printf("%n");
        for ( int n = 0 ; n <= max ; n++ ) {
            System.out.printf("%-3d", n);
            for ( int k = 0 ; k <= n ; k++ ) {
                System.out.printf("%10s", sterling2(n, k));
            }
            System.out.printf("%n");
        }
        System.out.println("The maximum value of S2(100, k) = ");
        BigInteger previous = BigInteger.ZERO;
        for ( int k = 1 ; k <= 100 ; k++ ) {
            BigInteger current = sterling2(100, k);
            if ( current.compareTo(previous) > 0 ) {
                previous = current;
            }
            else {
                System.out.printf("%s%n(%d digits, k = %d)%n", previous, previous.toString().length(), k-1);
                break;
            }
        }
    }
    
    private static Map<String,BigInteger> COMPUTED = new HashMap<>();
    
    private static final BigInteger sterling2(int n, int k) {
        String key = n + "," + k;
        if ( COMPUTED.containsKey(key) ) {
            return COMPUTED.get(key);
        }
        if ( n == 0 && k == 0 ) {
            return BigInteger.valueOf(1);
        }
        if ( (n > 0 && k == 0) || (n == 0 && k > 0) ) {
            return BigInteger.ZERO; 
        }
        if ( n == k ) {
            return BigInteger.valueOf(1);
        }
        if ( k > n ) {
            return BigInteger.ZERO;
        }
        BigInteger result = BigInteger.valueOf(k).multiply(sterling2(n-1, k)).add(sterling2(n-1, k-1));
        COMPUTED.put(key, result);
        return result;
    }

}