Я новичок в Java, и я все еще учусь. В рамках моего обучения я взял на себя задачу написать программу, которая будет принимать строку и проверять, есть ли какие-либо слова длиной 5 или более, и если да, то она будет переворачивать символы в 5+ длинных словах. . Задача состояла в том, чтобы сделать это без использования Collections.reverse(list) или StringBuilder.
Моя идея была, я бы сказал, просто написать 2 метода. Main разделит строку и будет выполнять итерацию по каждому индексу массива строк в поисках 5+ длинных слов, а метод, называемый «обратный», будет запускаться внутри условия «если». Похоже, этот работает нормально. Для обратного метода идея состояла в том, чтобы разбить слово на массив, а затем с помощью 2-х вложенных циклов for выполнить итерацию по индексам массивов ori и вспомогательных массивов rev, чтобы присвоить значение индекса ori[i] индексу rev [ж].
Таким образом, начиная с i=0 и j=arr.length-1, результатом будет присвоение значения "s" из слова предложения в ori[0] до rev[7], затем "e" из ori[1] до rev[6 ] и так далее, так что результатом будет [e, c, n, e, t, n, e, s]
Вместо этого я получаю вывод следующим образом:
[This, [e, e, e, e, e, e, e, e], will, [n, n, n, n, n, n, n], [s, s, s, s, s], with, more, than, five, [., ., ., ., ., ., ., .]]
Я пытался исправить это многими способами, но пока моя логика не работает. Может кто-нибудь объяснить мне, пожалуйста, что я делаю неправильно, как я испортил эту, казалось бы, простую логику?
Позже я разберусь, как отобразить это как обычное предложение без квадратных скобок и запятых, так что пока это не проблема.
Код:
import java.util.Arrays;
public class Main {
public static void main (String[] args) {
String original = "This sentence will contain words with more than five letters.";
String[] splitter = original.split(" ");
for (int i = 0; i < splitter.length; i++){
if (splitter[i].length() >= 5){
splitter[i] = reverse(splitter[i]);
}
}
System.out.println(Arrays.toString(splitter));
}
public static String reverse (String s){
String [] ori = s.split("");
String [] rev = new String[ori.length];
for (int i = 0; i < rev.length; i++) {
for (int j = rev.length-1; j >=0; j--) {
rev[j] = ori[i];
}
}
s = Arrays.toString(rev);
return s;
}
}
Пожалуйста, поймите новичка :)
Я попытался изменить эту часть:
public static String reverse (String s){
String [] ori = s.split("");
String [] rev = new String[ori.length];
for (int i = 0; i < rev.length; i++) {
for (int j = rev.length-1; j >=0; j--) {
rev[j] = ori[i];
поменяв местами i/j, rev[i] = ori[j], --j, j > 0 и многие другие, в основном слепые снимки в поисках вдохновения там, где моя логика терпит неудачу.
«Подсказка: вы можете выполнить реверсирование с помощью одного цикла for и одновременно изменить i и j внутри него» — спасибо, я попробую! «Подсказка 2: ваш код прямо сейчас эффективно заполняет массив rev последним символом из массива ori, и вы выполняете итерацию по массиву rev rev.length раз». - Я задал вопрос утке, почему она заполняет только последние буквы, и нашел этот ответ буквально через минуту после написания поста, спасибо!
Nitpick: split
— довольно дорогая операция для разделения слова на символы (потому что она использует регулярное выражение). Вы должны использовать getChars
. Бонус: некоторые символы (например, смайлики) не будут выглядеть правильно, если просто перевернуть их.
Спасибо @M.Prokhorov, я это запомню :) Позже я попытаюсь изменить весь код, чтобы использовать getChars :)
@MichałKrzywański после вашего удара это выглядит так: public static String reverse (String s){ String [] ori = s.split(""); String [] rev = new String[ori.length]; for (int i = 0, j = rev.length - i - 1; i < rev.length; i++, j--) { rev[j] = ori[i]; } s = Arrays.toString(rev); return s;
И это работает просто отлично, я понятия не имел, что могу изменить 2 переменные в одном цикле for, так что это действительно ценный удар для меня :) в любом случае решение Аммара выглядит намного лучше, так что я буду держись своего :)
Привет, Павел Неволак, у тебя проблема с реверсивной функцией.
В зависимости от ваших требований используйте это:
public static String reverse(String s) {
String[] ori = s.split("");
String[] rev = new String[ori.length];
for (int i = 0; i < rev.length; i++) {
rev[i] = ori[rev.length - i - 1];
}
s = "";
for (String str : rev) {
s += str;
}
return s;
}
}
The challenge was to do it without using Collections.reverse(list) or StringBuilder.
хорошо, позвольте мне отредактировать это
О, чувак, это гениально! К сожалению, я не могу проголосовать: Спасибо за отзыв! Чтобы проголосовать, вам нужно как минимум 15 репутации, но ваши отзывы были записаны.
Нет проблем. получайте удовольствие от этого
Вот еще одна возможность, которая использует существующий массив символов.
String.toCharArray()
new String(array)
public static String reverse(String s) {
char[] array = s.toCharArray();
for (int i = 0; i <array.length/2; i++) {
char ch = array[i];
array[i] = array[array.length-i-1];
array[array.length-i-1] = ch;
}
return new String(array);
}
Обратите внимание, что для строк четной длины два средних символа меняются местами. Для строк нечетной длины средний символ остается нетронутым.
Подсказка: вы можете сделать реверсирование с помощью одного цикла
for
и одновременно изменитьi
иj
внутри него. Подсказка 2: ваш код прямо сейчас эффективно заполняет массивrev
последним символом из массиваori
, и вы перебираете массивrev
rev.length
раз.