Повтор участка кода по заданному значению int. Помогите решить задачку по шифрованию :)
Всем доброго дня! Решаю задачку, суть которой следующая: Методу дается строка String text и число int n. Все эти данные передаются в final статусе. Необходимо отделить все четные знаки в text от нечетных и проделать это столько раз, сколько задано в n. Если n=0 или -n, то ничего не делается.
К примеру, "This is a test!" при n=1 ---> "hsi etTi sats!", а при n=2 *"s eT ashi tist!"*и так далее. Эта перестановка должна быть, скажем так, n-times.
Не много покипев мозгами я пришел к следующему:
public static String encrypt(final String text, final int n){
String result ="";
int t = n;// временная переменная t для подсчета кол-ва проходов шифрования
Character [] textArr = new Character[text.length()];
for (int i = 0;i<text.length();i++){
textArr[i] = text.charAt(i);
}
List<Character> charArr = Arrays.asList(textArr);
List<Character> oddCharArr = new ArrayList<>();
List<Character> evenCharArr = new ArrayList<>();
List<Character> tempCharArr = new ArrayList<>(charArr);
for (int i = 0; i < tempCharArr.size(); i++) {
if (i % 2 == 0) {
evenCharArr.add(tempCharArr.get(i));
} else oddCharArr.add(tempCharArr.get(i));
tempCharArr.addAll(oddCharArr);
tempCharArr.addAll(evenCharArr);
}
Мысль такая, строку разделить на массив Char, а за тем циклом пройти по этому массиву и разделить все четные и нечётные символы на два доп. массива. За тем, финальный массив перевести в строку. В моем случае я делаю через List.
Перестановка вроде получилась. Массив собирается правильно, но только один раз.
Пытался сделать через while, но безуспешно. Подскажите, как мне лучше и эффективнее сделать это действие n-раз?
И сразу вопрос в догонку, в другом методе надо вернуть все как было изначально. Подскажите, или хотя бы намекните алгоритм как это сделать :)
Заранее благодарю!
UPD (для Дмитрий Алексеенко):
public static String encrypt(final String text, final int n) {
String result ="";
int t = n;// временная переменная t для подсчета кол-ва проходов шифрования
Character [] textArr = new Character[text.length()];
for (int i = 0;i<text.length();i++){
textArr[i] = text.charAt(i);
}
List<Character> charArr = Arrays.asList(textArr);
List<Character> oddCharArr = new ArrayList<>();
List<Character> evenCharArr = new ArrayList<>();
List<Character> tempCharArr = new ArrayList<>();
for (int i = 0; i < charArr.size(); i++) {
if (i % 2 == 0) {
evenCharArr.add(charArr.get(i));
} else oddCharArr.add(charArr.get(i));
}
tempCharArr.addAll(oddCharArr);
tempCharArr.addAll(evenCharArr);
System.out.println(tempCharArr.toString());
return result;
}
Надеюсь на помощь)) Выше выложил код, который работает, но всего один раз.
Теперь надо сделать так, чтобы он делал эту перестановку заданное кол-во раз. Вот с этим у меня и проблемы. Неделю голову выношу себе и нарываюсь на бесконечные циклы)
Можете хотя бы подсказать как тут лучше это реализовать? А то вообще грусть(
Ответы (2 шт):
думаю можно попробовать как-то так
public static void main(String[] args) {
// String result ="";
String text = "This is a test!";
int t = 2;// временная переменная t для подсчета кол-ва проходов шифрования
while (t != 0) {
List<String> blablaList = getBlaBlaList(text);
text = blablaConvert(blablaList);
t--;
}
System.out.println(text);
}
public static List<String> getBlaBlaList(String text) {
List<String> ret = new ArrayList<>();
List<String> even = new ArrayList<>();
List<String> odd = new ArrayList<>();
for (int i = 0; i < text.length(); i++) {
if (i % 2 == 0) {
even.add(text.substring(i, i + 1));
continue;
}
odd.add(text.substring(i, i + 1));
}
ret.addAll(even);
ret.addAll(odd);
return ret;
}
public static String blablaConvert(List<String> blablaList) {
String ret = "";
for (int i = 0; i < blablaList.size(); i++) {
if (i % 2 == 0) {
ret += blablaList.get(i);
continue;
}
ret += blablaList.get(i);
}
return ret;
}
В качестве альтернативы предложу такой метод - вместо того, чтобы переколбашивать строку много раз, вычислим место, на которое встанет каждый символ после n преобразований, и поставим его сразу на нужное место. Аналогично можно сделать и с обратными преобразованием.
Замечу, что для каждой длины строки есть значение p (вот оно), при котором строка возвращается в начальное состояние, поэтому в принципе для больших n можно делать n%p преобразований, ну да ладно, p нетривиально.
Демонстрация принципа на Python:
def shuf(s, n):
le = len(s)
half = (le) // 2
result = ['']*le # список такой же длины, как строка
for idx in range(0, le):
t = idx
for k in range(n):
t = (t + 1)%2 * half + t // 2
result[t] = s[idx]
return ''.join(result) #склейка символов из списка в строку
for n in range(1,5):
print(n, shuf("This is a test!", n))
1 hsi etTi sats!
2 s eT ashi tist!
3 Tah itse sits!
4 This is a test!