如果我有一个像telephone
这样的字符串,并希望输出返回tel*phon*
,我该怎么做?
程序会打印出字符串中的每个字母。如果这封信第一次出现,那我就写了。但如果再次出现,我会打印一个星号。
hello
将为hel*o
goodbye
将为go*dbye
coordination
将为co*rdinat***
请帮助谢谢!这不是功课......这是最后的实践!谢谢!
我正在尝试这样的事情......但我只是不知道如何进一步......请帮助
import java.util.Scanner;
public class firstOccurrence{
public static void main(String[] args){
Scanner keyboard = new Scanner(System.in);
String s;
int i, j, count;
System.out.print("Enter string: ");
s = keyboard.nextLine();
for(i = 0; i < s.length(); i++){
count = 0;
for(j = i+1; i < s.length(); j++){
if(s.charAt(i) == s.charAt(j))
count++;
}
if(count < 1)
System.out.print(s.charAt(i));
else
System.out.print("*");
}
}
}
如何编辑此确切代码以使其正常工作?请帮忙:(
答案 0 :(得分:2)
Scanner keyboard = new Scanner(System.in);
String s;
System.out.print("Enter string: ");
s = keyboard.nextLine();
Set<Character> occur=new HashSet<Character>();
StringBuilder stb=new StringBuilder();
for(int i=0;i<s.length();i++){
if(occur.contains(s.charAt(i)))
stb.append("*");
else
stb.append(s.charAt(i));
occur.add(s.charAt(i));
}
System.out.println(stb.toString());
使用本规范,由于两个原因,它更加得体:
PS:代码已经过测试
答案 1 :(得分:0)
another answer给出了解决这个问题的简单方法。它迭代输入字符串的每个字符,并构建一组到目前为止看到的字符,使用当前字符构建输出StringBuilder
,或者如果已经看到当前字符则替换它。
这个问题似乎应该适合Java 8流处理。有一个新功能String.chars()
可将String
转换为Stream
char
。 (但是没有CharStream
,因此每个char
都表示为int
,流类型为IntStream
。
为此,我们要编写一个mapper函数,该函数可能会替换带有替换字符的字符,但前提是该字符已被查看过。因此,我们需要一个有状态映射器函数,这有点不寻常。但是,使用高阶函数编写一个函数并不困难:
public static IntUnaryOperator replaceIfSeen(int replacement) {
Map<Integer,Boolean> seen = new ConcurrentHashMap<>();
return i -> seen.putIfAbsent(i, Boolean.TRUE) == null ? i : replacement;
}
处理基本相同,只是它的包装方式不同。 replaceIfSeen
函数返回一个映射器函数,用于在地图中构建所看到的字符。 (没有ConcurrentHashSet
因此我们使用地图,但它基本相同。)如果第一次遇到输入字符,则mapper函数返回输入字符,如果已经遇到替换字符,则返回替换字符。它的使用方式如下:
static String replace(String input) {
return input.chars()
.map(replaceIfSeen('*'))
.mapToObj(i -> String.valueOf((char)i))
.collect(joining());
}
我们获取输入字符串并将其转换为char流(表示为int
)并在其上调用我们的条件映射器函数,要求它用*
字符替换重复项。 mapToObj
操作有点皱纹,因为我们需要将char
的{{1}}部分转换为单字符字符串。然后我们收集并将这些单字符串连接到输出中。结果如OP所预期的那样。
请注意,如果流并行运行,则行为会有所不同。它仍然有效,因为任何给定字符只出现一次,其他所有字符都被int
替换。不同之处在于未替换的角色可能不是第一个。例如,给定输入字符串*
,结果可能是coordination
。
答案 2 :(得分:0)
这是一个正则表达式方法来解决这个问题,一个可以在不使用任何外部容器来跟踪替换的情况下工作的问题:
String s = "coordination";
while(s.matches(".*?(\\w)(?=.*?\\1).*")) {
s = s.replaceAll("(?<=(\\w))((?:(?!\\1).)*)\\1", "$2*");
}
System.out.println( s );
//=> co*rdinat***
<强>解释强>
(?<=(\\w))
中的字母。 ((?:(?!\\1).)*)
将匹配除第一个捕获的字母之外的所有字符\\1
匹配组#1 regex101