Преобразование значений в строке Java с множителем

#java

#java

Вопрос:

Я заинтересован в умножении всех чисел в строке Java на параметр (x), как в следующем примере, где x = 5.

 Initial Input: "I have 10 tickets, 5 sodas and 20 snacks to sell."
  
 Target Output: "I have 50 tickets, 25 sodas and 100 snacks to sell."
  

Я попробовал следующий код на Java, но он не выдал «целевой результат». Я также пытался создать цикл for, повторяющий строку и умножающий любые числа на (x), но это тоже не сработало. Как можно получить желаемый результат на Java?

 public String transformOutput(int x){
   string = string.replaceAll("\d", "\d" * n)
   return string
}
  

Комментарии:

1. Готов поспорить, что это не привело к целевому выводу, поскольку это недопустимый синтаксис Java и даже не компилируется!

2. Несколько советов для вашего домашнего задания: Pattern и Matcher .

Ответ №1:

Получите числа с помощью регулярного выражения и используйте Matcher.appendReplacement для замены

 import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) throws Exception {
        String input = "I have 10 tickets, 5 sodas and 20 snacks to sell.";
        System.out.println(transformOutput(5, input));
    }

    public static String transformOutput(int x, String str) {
        Pattern pattern = Pattern.compile("\d ");
        Matcher matcher = pattern.matcher(str);
        StringBuffer buffer = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(buffer, String.valueOf(Integer.parseInt(matcher.group()) * x));
        }
        matcher.appendTail(buffer);        
        return buffer.toString();
    }
}
  

Ответ №2:

Использование потоков Java 8 :

 public String transform(String input, int multiplicator) {
    return Pattern.compile(" ")
            .splitAsStream(input)
            .map(token -> {
                try {
                    return ""   multiplicator * Integer.parseInt(token.trim());
                } catch (NumberFormatException e) {
                    return token;
                }
            })
            .collect(Collectors.joining(" "));
}


@Test
public void test() {
    String input = "I have 10 tickets, 5 sodas and 20 snacks to sell.";
    String output = transform(input, 5);
    assertEquals("I have 50 tickets, 25 sodas and 100 snacks to sell.", output);
}
  

Ответ №3:

Вот один из способов сделать это. Это работает следующим образом: Примечание: Основываясь на вашем примере, я предполагаю, что вы не хотите, чтобы числа были встроены в слова (например, foo25).

  • Разделите строку на один или несколько пробелов.

  • Поток последующего массива токенов.

  • выборочно сопоставьте токен со значением, если оно соответствует всем цифрам, в противном случае просто верните слово без изменений. Это делается с помощью ternary(?:) оператора. Выражение a ? b : c говорит, что если a это true, сделайте b , иначе сделайте c .

    .map(st -> st.matches("\d ") ? (Integer.valueOf(st) * n) "" : st)

    • если строка, st , соответствует числу, преобразуйте в целое число и умножьте на n .
    • в противном случае просто верните строку.
  • Затем снова объедините поток в строку, используя Collectors.join(" ")

    • принимает разделитель и объединяет конкатенаты, используя предоставленный разделитель (в данном случае пробел).
 import java.util.Arrays;
import java.util.stream.Collectors;

String str =                                                 
        "I have 10 tickets, 5 sodas and 20 snacks to sell."; 
String tstr = transformOutput(str, 5);                       
System.out.println(tstr);                                    
                                                              
                                                                 
public static String transformOutput(String str, int n) {        
    return Arrays                                                
            .stream(str.split("\s "))                           
            .map(st -> st.matches("\d ") ?                      
                    (Integer.valueOf(st) * n)   "" : st)         
            .collect(Collectors.joining(" "));                   
                                                                 
}
  

С принтами

 I have 50 tickets, 25 sodas and 100 snacks to sell.
                                                               
  

Комментарии:

1. Как именно строки (i) .map(st -> st.совпадают(«\ d «)? (Integer.valueOf(st) * n) «» : st) И (ii) .собирать (Collectors.joining(» «)) работает? Кроме того, нужно ли импортировать какие-либо пакеты для работы этой части кода (например, сборщики)?

2. Ответ изменен в соответствии с вашими вопросами.

3. Как именно вы запускаете код? Я попытался запустить приведенный выше код на некоторых онлайн-компиляторах Java (например tutorialspoint.com/compile_java_online.php , jdoodle.com/online-java-compiler ), но я получаю сообщение об ошибке, что общедоступный класс не найден.

4. Это просто существенные моменты. Его нужно поместить в класс, а среднюю часть поместить в метод main. Это основа программирования на Java.

Ответ №4:

добро пожаловать в StackOverflow. Идея, которая у вас есть, хорошая, использование регулярных выражений имеет смысл, но, к сожалению, так не сработает. Функция replace находит все числа для замены, но может заменить их только одним значением.

Один из подходов, который мог бы сработать, — это найти все числа по отдельности, а затем заменить их. Это похоже на домашнее задание, поэтому я не собираюсь предоставлять реальное решение, и вы уже достаточно близки к нему самостоятельно!