Как в строке одновременно заменить "." на "!" и "!" на "."
Я решил попробовать заменить все точки в строке на ! и одновременно наоборот( т.е ".!.!" -> "!.!."), но не очень понимаю , как это сделать и возможно ли это вообще.
Пробовал сделать это через .replace()
Ответы (6 шт):
Можно, например, через стримы
допустим, s - это строка, тогда новая строка:
Stream.iterate(0, i -> i + 1)
.limit(s.length())
.map(x -> s.charAt(x) == '.' ? '!' : (s.charAt(x) == '!' ? '.' : s.charAt(x)))
.map(x -> x.toString())
.collect(Collectors.joining());
Небольшое извращение с регулярками, асимптотика квадратичная: https://ideone.com/prUYqn
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";
var res = (str + ".!").replaceAll("..$|\\.(?=.*?(!))|!(?=.*(\\.))", "$1$2");
System.out.println(str);
System.out.println(res);
}
}
a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!
Нормальный вариант с регулярками: https://ideone.com/02Z0vQ
import java.util.*;
import java.util.regex.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";
var res = Pattern.compile("[.!]").matcher(str)
.replaceAll(m -> m.group().equals(".") ? "!" : ".");
System.out.println(str);
System.out.println(res);
}
}
a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!
Также предложу свой вариант:
String s = ".!.!.!...!";
s = s.replaceAll("\\.", ",").replaceAll("!", ".").replaceAll(",", "!");
P. S в первом replaceAll, там два слеша
Если хочется попридумывать алгоритмы: https://ideone.com/Y2BLPt
import java.util.*;
import java.util.regex.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";
var res = str
.replaceAll("\\.", "..")
.replaceAll("!", ".!")
.replaceAll("\\.\\.", "!")
.replaceAll("\\.!", ".")
;
System.out.println(str);
System.out.println(res);
}
}
a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!
нормальный алгоритм с преобразованием в массив char'ов, циклом и созданием строки:
var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";
var arr = str.toCharArray();
for (int i = 0, n = arr.length; i < n; i++) {
if (arr[i] == '!') {
arr[i] = '.';
} else if (arr[i] == '.') {
arr[i] = '!';
}
}
var rep = new String(arr);
System.out.println(str);
System.out.println(rep);
Результат:
a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!
Если нужно преобразовывать не два, а больше символов, можно использовать switch вместо if / else if:
// Java 12+
static String replacer(String str) {
if (null == str || str.isEmpty()) return str;
var arr = str.toCharArray();
for (int i = 0, n = arr.length; i < n; i++) {
arr[i] = switch(arr[i]) {
case '.' -> '!';
case '!' -> '.';
default -> arr[i];
};
}
return new String(arr);
}
или карту символов со стримами :)
static final Map<Character, Character> MAP = Map.of(
'.', '!',
'!', '.'
);
static String convert(String str) {
if (null == str || str.isEmpty()) return str;
return str.chars() // IntStream
.mapToObj(c -> MAP.getOrDefault((char) c, (char) c)) // Stream<Character>
.collect(Collector.of( // идиома для преобразования Stream<Character> в String
StringBuilder::new, (bld, c) -> bld.append(c.charValue()),
StringBuilder::append, StringBuilder::toString
));
}