完成该方法,以便将单词格式化为单个逗号分隔值。最后一个单词应该用“和”而不是逗号分隔。应忽略空字符串值。传递给方法的空数组或null / nil值应该返回一个空字符串。
示例:
{"ninja", "samurai", "ronin"}) => "ninja, samurai and ronin"
{"ninja", "", "ronin"}) => "ninja and ronin"
代码
public static String formatWords(String[] words)
{
if (words == null || words.length == 0)
{
return "";
}
String str = "";
for (int i = 0; i < words.length; i++)
{
if (words[i].equals(""))
continue;
if (i == words.length - 1)
str += "and " + words[i];
else
str += words[i] + ", ";
}
return str;
}
如何删除最后一个逗号?
答案 0 :(得分:3)
一个简单的解决方案是按降序运行循环。我对您的代码进行了一些更改..希望,这有效
public static String formatWords(String[] words)
{
Vector<String> v= new Vector<String>();
if (words == null || words.length == 0)
return "";
for (int i = 0; i < words.length; i++)
if (!words[i].equals("")) v.add(words[i]);
String str="";
for (int i = v.size()-1; i >= 0; i--)
{
if(str.equals("")){
if(i>0)
str = " and " + v.get(i);
else
str = v.get(i);
}else{
if(i==0)
str = v.get(i) + str;
else
str = "," + v.get(i) + str;
}
}
return str;
}
编辑:修改了添加Vector以解决@AJNeufeld在评论中提到的问题
答案 1 :(得分:2)
您可以使用String.join
使用逗号创建String
。然后用正则表达式替换最后一个逗号。
String[] values = {"ninja", "samurai", "ronin"};
//Join each values with ", "
String phrase = String.join(", ", values);
System.out.println(phrase); //ninja, samurai, ronin
//Replace the last "," with " and"
phrase = phrase.replaceFirst(",([^,]+)$", " and$1");
System.out.println(phrase); //ninja, samurai and ronin
这是在一行中完成的:
String phrase = String.join(", ", values).replaceFirst(",([^,]+)$", " and$1");
使用方法进行快速测试时可以看到结果:
public static String createPhrase(String[] values){
return String.join(", ", values).replaceFirst(",([^,]+)$", " and$1");
}
System.out.println(createPhrase(new String[] {"ninja"} ));
System.out.println(createPhrase(new String[] {"ninja", "samurai"}));
System.out.println(createPhrase(new String[] {"ninja", "samurai", "ronin"}));
忍者
忍者和武士郎 忍者,武士和浪人
注意:
要管理数组中的空值和空值,最简单的方法是使用Stream
Stream.of(values)
.filter(s -> s != null && !s.isEmpty())
.collect(joining(", "))
然后使用相同的正则表达式来管理" and"
部分。
答案 2 :(得分:0)
一种常见的技术是引入“分隔符”变量。在第一次迭代时,它是空字符串,然后大部分时间是", "
,在最后一次迭代时它是" and "
。
最佳做法是在重复附加StringBuilder
时使用String
,以避免重复(浪费)内存分配。
public static String formatWords(String[] words) {
if (words == null || words.length == 0) {
return "";
}
StringBuilder ans = new StringBuilder();
for (int i = 0; i < words.length; i++) {
String sep = ", ";
if (i == 0)
sep = "";
else if (i == words.length - 1)
sep = " and ";
ans.append(sep).append(words[i]);
}
return ans.toString();
}
答案 3 :(得分:0)
如果您使用的是Java 8,解决方案可以简化如下:
public static String formatWords(String[] words) {
String res = Arrays.asList(words)
.stream()
.filter(word -> !(word == null))
.filter(word -> !word.equals(""))
.collect(Collectors.joining(","));
if(! res.contains(","))
return res;
int indexOfLastComma = res.lastIndexOf(",");
String resultuntilLastWord = res.substring(0, indexOfLastComma);
String lastWord = res.substring(indexOfLastComma + 1);
res = resultuntilLastWord + " and " + lastWord;
return res;
}
首先在代码中构造一个结果String(res
),所有分隔符都是逗号。
然后,获取字符串中最后一个逗号的索引并创建两个子字符串。一个子字符串应该是字符串中的最后一个逗号:
String resultuntilLastWord = res.substring(0, indexOfLastComma);
和其他应该直到字符串的结尾:
String lastWord = res.substring(indexOfLastComma + 1);
最后将这两个子串合并为" and "
。
答案 4 :(得分:0)
我觉得这是一项家庭作业,所以我不打算给你完整的解决方案,但是我会指出你正确的轨道,而不使用像ArrayList<String>
,{{{{{}}这样的高级概念。 1}},Vector<String>
和正则表达式,可能还没有被教过。
此作业中的最大挑战是正确跳过Stream.of(...)
数组中的null
/ nil值,并仍然找到逗号分隔符和最终words
分隔符的正确位置。循环遍历" and "
数组时,words
条目不一定标记第一个真实单词,因为数组可能以i == 0
或空null
开头。同样,String
条目不一定代表最后一个单词,因为数组可能以i == words.length-1
或空null
结尾。这意味着循环索引String
实际上无用于确定是否需要分隔符以及使用哪个分隔符。
由于循环索引或多或少没用,我们可以使用“enhanced for-loop”构造来循环遍历数组中的单词:
i
如果您还没有学习“增强型for循环”,您可以坚持:
for(String word : words) {
// ... code here
}
但请理解,您不会在循环内的任何其他位置使用值for(int i = 0; i < words.length; i++) {
String word = words[i];
// ... code here
}
。因此,我将继续在讨论的其余部分使用“增强的for循环”,但是知道这是一个简单的替换,将其更改为常规的for循环。
您需要知道的第一件事是“i
数组中有多少个单词?”答案不是words
,因为words.length
值和空null
值的可能性。最简单的方法是使用循环计算有效单词:
String
通过知道有int numWords = 0;
for(String word : words) {
if (word != null && !word.isEmpty()) {
numWords++;
}
}
个单词,您现在可以果断地说numWord
分隔符位于最后一个单词之前,这个单词将从" and "
开始(从1开始计算)字。
考虑到这一点,您现在可以执行第二个循环,查看每个单词,并决定是否将其视为有效单词,并仅为有效单词更新numWords
。
wordNumber
我遗漏了添加单词和相应分隔符的最后一步的实际代码。这与OP解决问题的初始尝试没有太大的不同,因此应该明白如何继续,但不是Stack-Overflow的复制和粘贴作业解决方案。学生至少做了一些工作。
上述解决方案使用两个for循环;第一个计算有效单词的数量,第二个计算单词。将数据循环一次通常更好。这允许您处理数据流,其中数据是暂时的或短暂的,您可能没有第二次机会读取数据。
显然,在这个例子中并非如此。数据在一个数组中;您可以根据需要多次循环数据。但是仍然可以只使用一个循环来进行操作。
使用一个循环处理数据更复杂。诀窍是保留最近的单词,并将其延迟添加到结果中,直到您知道要使用哪个分隔符(如果有)将其添加到结果中。当你完成所有单词的循环时,你将得到一个部分结果,以及最近的(又名,最后一个)单词。此时,你只需要在结果中添加最后一个单词,加上单词“and”,除非它也是第一个单词。
String result = "";
int wordNumber = 0;
for(String word : words) {
if (words != null && !word.isEmpty()) {
wordNumber++;
// If not the first word, then add a separator (either a
// comma or the word "and" if at the last word) to result.
// Then, add word to result.
}
}
同样,我遗漏了确定是否需要分隔符的关键代码,并将其和最新的单词添加到结果中。再次,请留给学生,以避免从Stack-Overflow家庭作业解决方案中复制和粘贴。
如其他地方所述,使用String result = "";
String most_recent_word = null;
for(String word : words) {
if (word != null && !word.isEmpty()) {
if (most_recent_word != null) {
// Add most_recent_word to result, preceded by a comma if necessary
}
most_recent_word = word;
}
}
if (most_recent_word != null) {
// Add most_recent_word to result, preceded by " and " if necessary
}
构建最终StringBuilder
可以提高上述两种解决方案的代码效率。这不是必需的,但是如果你被教会如何使用它,你应该使用它!