【问题标题】:Reverse a string word by word except the last letter of each word除每个单词的最后一个字母外,逐字反转字符串
【发布时间】:2021-01-11 01:58:42
【问题描述】:

除了每个单词的最后一个字母之外,我想逐字反转字符串。

例如:"Hello how are you" -> lleHo ohw rae oyu

但我得到的输出是:olleH woh era uoy

我无法修正每个单词的最后一个字母。

这是我上面输出的 Java 代码:

public class Main

    {
    public static void main(String[] args) {
     String s = "Hello how are you  ";
      char [] ch = s.toCharArray();
      System.out.println(ch.length);
      int pos=0;
        for(int i=0;i<ch.length;i++)
        {
        
            if(ch[i]==' ')
            {
                   
                for(int j=i;j>=pos;j--)
                {
                    System.out.print(ch[j]);
                }
                pos=i+1;
                }
            }
    
    }
} 

【问题讨论】:

  • 您是否使用调试器单步调试您的代码?您可能想向前看,是否已经击中了单词中的最后一个字符来以不同的方式处理它。根据您的代码,单词的最后一个字符似乎后跟一个空格或字符串的结尾。

标签: java arrays string character


【解决方案1】:

下面是解决问题的办法:

public class Main { 
    
    public static void main(String[] args) { 
        //call the reverseSentence Method
        reverseSentence("Hello how are you");
    } 
    
    public static void reverseSentence(String sentence) {
        

        //Replacing multiple space with a single space
        sentence = sentence.replaceAll("[ ]{2,}", " ");

        //Split the array and store in an array
        String [] arr = sentence.split(" ");
        
        StringBuilder finalString = new StringBuilder();
        
        //Iterate through the array using forEach loop
        for(String str : arr) {
            
            //Creating substring of the word, leaving the last letter
            String s = str.substring(0, str.length() - 1);
            
            //Creating StringBuilder object and reversing the String
            StringBuilder sb = new StringBuilder(s);
            //Reversing the string and adding the last letter of the work again.
            s = sb.reverse().toString() + str.charAt(str.length() - 1);
            
            //Merging it with the final result
            finalString.append(s).append(" ");
        }
        
        //Printing the final result
        System.out.println(finalString.toString().trim());
    }
} 

我所做的是,首先将所有单词拆分为空格并将其存储在一个数组中。现在遍历数组并从每个单词中获取子字符串,留下每个单词的最后一个字母。然后我使用 StringBuilder 来反转字符串。完成后,我将单词的最后一个字母添加到反转的字符串中,并将其与创建的 finalString 合并。

【讨论】:

  • 说实话,我不太喜欢为这类问题发布完整的解决方案。 OP 需要学习一两件事,因此应该帮助他们找到自己的解决方案。至少添加一些关于你所做的事情的描述,以便其他人可以更轻松地遵循代码。
  • 欢迎来到 SO!仅供参考,这在 "foo bar baz" 等上失败,并在结果中添加一个尾随 " " 字符。最好返回结果并让调用者打印以避免对函数产生副作用。我会为finalString 使用StringBuilder 来避免Schlemiel the painter's algorithm
  • @ggorlen 我已经进行了更改,您提到的两个问题现在都已处理。
  • @ggorlen 我明白你的意思,因为长句子连接 String 不是一个好方法,而是将它附加到 StringBuilder 并转换成 String 是一种更好的方法。谢谢。
【解决方案2】:

更简单的解决方案是对每个单词(在 string.split 之后)使用 Java Stack 数据结构,然后添加每个字母(token.length-1 除外)。

public static void main(String[] args) {
    String string = "Hello how are you  ";
    final String[] tokens = string.split(" ");
    for (String token : tokens) {
        final Stack<Character> stack = new Stack<Character>();
        for (int i = 0; i < token.length()-1; i++) {
            stack.push(token.charAt(i));
        }
        while (!stack.empty()) {
            System.out.print(stack.pop());
        }
        System.out.print(token.charAt(token.length()-1) + " ");
    }
}

【讨论】:

  • 不应该是评论吗?
  • @Thomas 不,这是一个解决方案。
  • 我明白了,这只是一个问题作为答案,可能会令人困惑:)
  • @Thomas 好点感谢您的指点。相应地修复。
【解决方案3】:

您如何看待这个解决方案?

public class Main
{
    public static void main(String[] args) {
        String s = "Hello how are you  ";
        char [] ch = s.toCharArray();
        System.out.println(ch.length);
        int pos=0;
        for(int i=0;i<ch.length;i++)
        {
        
            if(ch[i]==' ')
            {
                System.out.print(ch[i]);
                for(int j=i-2;j>=pos;j--)
                {
                    System.out.print(ch[j]);
                }
                System.out.print(ch[i-1]);
                pos=i+1;
            }
        }
    
    }
} 

【讨论】:

  • 此处相同(请参阅我对 Prateek 回答的评论):请至少添加一些关于您所做的事情以及原因的描述,以便您可以帮助 OP 遵循您的解决方案。
【解决方案4】:

我会使用带有 lambda 的正则表达式 replaceAll 来处理反转。 \S+ 匹配任何非空格字符序列。这具有优雅地处理任意空白的优点。如果你想避免颠倒标点符号,你可以使用\w+,尽管像​​"isn't" 这样的匹配词表明问题会转移到自然语言处理中。不过,我认为您的规范并不那么复杂。

import java.util.regex.Pattern;

class Main {
    public static void main(String[] args) {
        String res = Pattern
            .compile("\\S+")
            .matcher("Hello how are you")
            .replaceAll(m -> {
                String s = m.group();
                return new StringBuilder(s.substring(0, s.length() - 1))
                    .reverse().toString() + s.charAt(s.length() - 1);
             });
        System.out.println(res); // => lleHo ohw rae oyu
    }
}

【讨论】:

    【解决方案5】:
    public class Main {
        public static void main(String[] args) {
            String s = "Hello how are you  ";
            final List<String> list = Arrays.asList(s.split(" "));
            StringBuilder builder = new StringBuilder();
            list.forEach(item ->{
                StringBuilder itemBuilder = new StringBuilder(item);
                final String rStr = itemBuilder.reverse().toString();
                builder.append(rStr.substring(1,rStr.length())).append(rStr.substring(0,1)).append(" ");
            });
            System.out.println(builder.toString());
        }
    }
    

    【讨论】:

      【解决方案6】:

      FP 风格:

      String str = "Hello how are you";
      
      String res = Arrays.stream(str.split(" "))
        .map(s ->
          new StringBuilder(s.substring(0, s.length() - 1)).reverse().toString() + s.substring(s.length() - 1)
        )
        .reduce((s, s1) -> s + " " + s1)
        .orElse("");
      
      System.out.println(res); // lleHo ohw rae oyu
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-29
        • 1970-01-01
        • 1970-01-01
        • 2023-02-03
        • 1970-01-01
        • 2016-01-18
        相关资源
        最近更新 更多