Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Помогите решить задачу на Java:

Алексей Пахомов Ученик (11), на голосовании 1 год назад
Пытался решить сам, но не получается.
Сама задача:
Есть книга с рецептами, каждый рецепт хранится в отдельной строчке. Так же есть продукты, на которые у человека аллергия. Нужно заменить продукты-аллергены на указанный продукт, при этом сохранив регистр слова.
Входные данные:
На первой строке записывается натуральное число n - количество строчек в книге. Затем вводится n строк - строки книги. потом вводится натуральное число m - количество продуктов, на которые у человека аллергия. Потом вводится m строк - вида "продукт1 - продукт2", где продукт1 - продукт, на который у человека аллергия и продукт2 - продукт, на который следует заменить продукт1. Гарантируется что любой продукт состоит из 1 слова. название продуктов написаны строчными буквами. Гарантируется, что продукты, на которые нужно выполнить замену, не встречаются изначально в тексте.
Выходные данные:
Замените все продукты в поваренной книге Васи и выведите их построчно на экран. На окончания не обращайте внимание. ВАЖНО!!! Если продукт, который следует заменить написан с большой буквы, то и замена тоже должна начинаться с большой буквы!
Пример ввода:
2
Рецепт 1. Арахис 100гр, мороженое 200гр. Возьмите арахис и измелчите его. Посыпьте измельчённый арахис на мороженое.
Рецепт 2. Клубника 100гр, сгущенка 3кг. Смешать, есть) Радоваться жизни.
3
арахис - колбаса
клубника - вишня
сгущенка - молоко
Пример вывода:
Рецепт 1. Колбаса 100гр, мороженое 200гр. Возьмите колбаса и измелчите его. Посыпьте измельчённый колбаса на мороженое.
Рецепт 2. Вишня 100гр, молоко 3кг. Смешать, есть) Радоваться жизни.
У меня получилось заменить продукты, но только с нижним регистром. Я пару часов просидел, но так и не придумал.
Это код, который у меня получился:
 import java.util.Scanner; 

class MyProgram {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int numberOfLines = scan.nextInt();
scan.nextLine();
String[] lines = new String[numberOfLines];
for(int i = 0; i < numberOfLines; i++){
lines[i] = scan.nextLine();
}
int numberOfAllergens = scan.nextInt();
scan.nextLine();
String[] allergensAndReplaced = new String[numberOfAllergens];
for(int i = 0; i < numberOfAllergens; i++){
allergensAndReplaced[i] = scan.nextLine();
String[] replace = allergensAndReplaced[i].split(" - ");
for(int j = 0; j < numberOfLines; j++){
lines[j] = lines[j].replaceAll(replace[0], replace[1]);
}
}
for(int i = 0; i < numberOfLines; i++){
System.out.println(lines[i]);
}
}
}
Помогите дорешать эту задачу. Заранее спасибо.
P.s. троллей буду банить)
Голосование за лучший ответ
улюп улюпов Ученик (116) 1 год назад
Вы используете метод replaceAll для замены строк, который не сохраняет регистр заменяемых слов. Чтобы сохранить регистр заменяемых слов, вам нужно использовать более сложную логику:
 import java.util.Scanner; 

class MyProgram {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int numberOfLines = scan.nextInt();
scan.nextLine();
String[] lines = new String[numberOfLines];
for (int i = 0; i < numberOfLines; i++) {
lines[i] = scan.nextLine();
}
int numberOfAllergens = scan.nextInt();
scan.nextLine();
String[] allergensAndReplaced = new String[numberOfAllergens];
for (int i = 0; i < numberOfAllergens; i++) {
allergensAndReplaced[i] = scan.nextLine();
String[] replace = allergensAndReplaced[i].split(" - ");
String allergen = replace[0];
String replacement = replace[1];
for (int j = 0; j < numberOfLines; j++) {
lines[j] = replaceWordsWithMatchingCase(lines[j], allergen, replacement);
}
}
for (int i = 0; i < numberOfLines; i++) {
System.out.println(lines[i]);
}
}

private static String replaceWordsWithMatchingCase(String line, String target, String replacement) {
StringBuilder result = new StringBuilder();
int currentIndex = 0;
while (currentIndex < line.length()) {
int startIndex = line.indexOf(target, currentIndex);
if (startIndex == -1) {
result.append(line.substring(currentIndex));
break;
}
result.append(line.substring(currentIndex, startIndex));
if (startIndex > 0 && Character.isUpperCase(line.charAt(startIndex))) {
replacement = capitalizeFirstLetter(replacement);
}
result.append(replacement);
currentIndex = startIndex + target.length();
}
return result.toString();
}

private static String capitalizeFirstLetter(String word) {
return Character.toUpperCase(word.charAt(0)) + word.substring(1);
}
}
В данном коде функция replaceWordsWithMatchingCase осуществляет замену слов с сохранением регистра, а функция capitalizeFirstLetter делает первую букву слова заглавной. Это позволит заменить аллергены на указанные продукты, сохраняя регистр.
Sergio 2.1 Оракул (67303) 1 год назад
Да, вы на правильном пути, но забыли учесть, что слова могут начинаться с большой буквы. В этом случае, нужно убедиться, что замена сохраняет регистр. Воспользуйтесь тем фактом, что в Java вы можете использовать (?i) в регулярных выражениях, чтобы разрешить нечувствительность к регистру. И затем сделайте первую букву результирующего слова заглавной, если первая буква исходного слова была заглавной.

Вот обновленный фрагмент кода, который учитывает регистр:
 for(int i = 0; i < numberOfAllergens; i++){  
allergensAndReplaced[i] = scan.nextLine();
String[] replace = allergensAndReplaced[i].split(" - ");

for(int j = 0; j < numberOfLines; j++){
if (lines[j].toLowerCase().contains(replace[0])) {
lines[j] = lines[j].replaceAll("(?i)" + replace[0], Character.isUpperCase(lines[j].charAt(lines[j].toLowerCase().indexOf(replace[0]))) ? capitalize(replace[1]) : replace[1]);
}
}
}
Здесь я добавил еще одну функцию capitalize, которую вы можете использовать для преобразования первой буквы строки в верхний регистр:
 public static String capitalize(String str) { 
if(str == null || str.isEmpty()) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
Эта функция capitalize преобразует первую букву строки в верхний регистр и оставляет остальные символы без изменений.

Просим обратить внимание, что данный подход решает проблему с регистром только для первого упоминания продукта в каждой строке. Если продукт упоминается в начале предложения несколько раз, его следует обрабатывать отдельно.
Похожие вопросы