Вычисление строк по hashCode

207
15 января 2019, 11:10

Поставлена такая задача.

Есть метод Collection getStringsForHashCode(int hashCode, int length) На входе hashCode и length - кол-во символов в получаемой строке.

Метод должен найти все комбинации char-ов у которых сумма hashCode равна параметру метода и кол-во этих char-ов должно быть равно параметру length у метода.

Пример:

getStringsForHashCode(18,3) = {“dad”, “bbc”, “maa”, …. }

Подскажите как такое сделать? я вообще в тупике.

Небольшие условия:

  • hashCode считается так: hashCode(s) = sum (s[i] * (i+1)) где s строка, а i чар строки.
  • дан метод int getInt(char c);
  • дан метод char getChar(int c);
  • значение int у char равно от 1 до 26. То бишь getInt('a') = 1 и т.д.

Я честно хз как лучше решить. надо случайным образом брать чар и пытаться склеивать с другими. Или же идти от обратного: найти сумму цифр и потом по полученным цифрам найти char.

Буду очень благодарен помощи)

Answer 1

Как уже сказал Grundy это задача поиска целочисленных решений уравнения, лежащих в диапазоне 1..26.

1 * x1 + 2 * x2 + 3 * x3 + ... + n * xn = hash 

Можно считать её разновидностью задачи о наборе суммы - какие наборы из n монет с достоинством 1..26 дадут нужную сумму. Пример на Python.

По пределам отсечения: минимальное значение, которое можно набрать из n-1 первых символов, есть 1+2+3+4+..+n-1 = n*(n-1)/2, а максимальное - 26 умножить на это значение.

def getstr(hash, n, s):
    if (n==0):
        if (hash == 0):
            print(s)
        return
    for i in range(max(1, hash // n - 13 * (n-1)), min(26, (hash - (n * (n-1) //2))) // n + 1):
        getstr(hash - i * n, n - 1, chr(ord('a') + i - 1) + s)    
getstr(18, 3, "")
>>
maa
kba
ica
gda
eea
cfa
aga
jab
hbb
fcb
ddb
beb
gac
ebc
ccc
adc
dad
bbd
aae

Java code

class Ideone
{   
    public static void findStrs(int hash, int n, String s) {
    if (n==0) {
        System.out.println(s);
        return;
    }   
    int from = hash / n - 13 * (n-1);
    from = (from < 1)? 1: from;
    int to = (hash - (n * (n-1) / 2)) / n;
    to = (to > 26)? 26: to;
    for (int i = from; i<= to; i++){
        //System.out.println(i);
        findStrs(hash - i * n, n - 1, (char)(97 + i - 1) + s);   
    }
   return;
 } 
    public static void main (String[] args) throws java.lang.Exception
    {
       findStrs(18, 3, ""); // your code goes here
    }
}
Answer 2

Для оптимизации перебора можно ограничить максимальное значение элемента строки. Строка "ааа" уже генерирует hash = 1+2+3 = 6. И для третьего элемента нет смысла добавлять что то больше (18-1-2)/3 = 5 т.е. "е". Перебор для больших lenght и малых hash будет существенно сокращен. Например getStringsForHashCode(175, 18) даст следующую маску максимальных значений элементов, шестьдесят возможных вариантов и всего пять решений:

[5, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
eaaaaaaaaaaaaaaaaa
cbaaaaaaaaaaaaaaaa
acaaaaaaaaaaaaaaaa
babaaaaaaaaaaaaaaa
aaabaaaaaaaaaaaaaa
READ ALSO
Сортировка элементов в GridView

Сортировка элементов в GridView

// С Collectionssort(colors); показывает ошибку:

187
Запуск batом jar файлов

Запуск batом jar файлов

согласно требованиям проект должен запускаться из консоли вводом "compilebut && run

179
Как по нажатию на кнопку создать новое CardView?

Как по нажатию на кнопку создать новое CardView?

У меня есть CardView в которой 2 кнопки "добавить" и "удалить"При нажатии на кнопку "добавить" я перехожу на новую активити и там страница для создания...

145
Разница между методом init() и init(ServletConfig config)

Разница между методом init() и init(ServletConfig config)

Жизненный цикл сервлета начинается с запуска метода initВ абстрактном классе GenericServlet объявлено 2 варианта метода: init() и init(ServletConfig config)

162