【问题标题】:Java- Print individual words from a sequence of charactersJava-从字符序列中打印单个单词
【发布时间】:2021-11-02 01:40:35
【问题描述】:

我编写的方法应该返回推文中单个单词的列表。单词定义为 [a, z] 或 [A, Z] 范围内的字符。例如,“我讨厌我的工作”这句话应该打印出来: 一世 恨 我的 工作

这是我当前的实现。我还包括了此方法所需的私有成员变量:

public ArrayList<String> getWords() {
    ArrayList<String> words = new ArrayList();
    String st = "";
    for(int i = 0; i < content.length(); ++i) {
      char s = content.charAt(i);

      if(s == ' ' && st.equals("") == false) {
        words.add(st);
        st = ("");
      }
       if(s >= 'a' && s <= 'z' || s >= 'A' && s <= 'Z') {
        st += s;
      }
    }

    return words;
  }


  private String content;

这是输入“我讨厌我的工作”的当前输出:

  i
  hate
  my

预期输出: 一世 恨 我的 工作

这是我当前输入“我爱我的工作#winning”的输出:

 i

 love

 my

 job

预期输出:

我的

工作

获胜

为什么我的输出不正确?我不明白为什么它不打印最后的话?

【问题讨论】:

  • 你是怎么期望#winning变成winning的?为什么不根据空格分割字符串呢?
  • 最后一个单词后没有空格 (' '),因此您的 if 不会被调用,这意味着该单词不会添加到 words

标签: java string arraylist data-structures


【解决方案1】:
  • 简单修复:将st 添加到列表主循环之后。
  • 附加修复:使用String.isEmptyCharacter.isLetter等标准方法
  • 使用StringBuilder而不是字符串来累加每个单词(那么应该使用st.length() &gt; 0)。
public ArrayList<String> getWords() {
    ArrayList<String> words = new ArrayList<>();
    StringBuilder st = new StringBuilder();
    for(int i = 0; i < content.length(); ++i) {
        char c = content.charAt(i);

        if (Character.isWhitespace(c) && st.length() > 0) {
            words.add(st.toString());
            st.setLength(0); // clear string builder
        }

        if(Character.isLetter(c)) {
            st.append(c);
        }
    }
    if (st.length() > 0) {
        words.add(st.toString());
    }

    return words;
}

但是,最好使用方法String::split,获取字符串数组并将其转换为列表,使用接口List而不是具体实现:

public List<String> getWords() {
    return Arrays.asList(content.split("[^a-zA-Z]+"));
}

这里的正则表达式"[^a-zA-Z]+"表示单词分隔符是任何非英文字母字符(量词+表示至少1个字符)。

【讨论】:

    【解决方案2】:

    以下是修复代码的方法。它没有添加最后一个单词,因为下面的第二个 if 条件永远不会得到满足。如果您在输入字符串的末尾添加一个空格,它将按您的预期显示。

    public static ArrayList<String> getWordss(String content) {
            ArrayList<String> words = new ArrayList();
            String st = "";
            for(int i = 0; i < content.length(); i++) {
                char s = content.charAt(i);
                if (i == content.length()  - 1) {
                    st += s;
                    words.add(st);
                }
                if(s == ' ' && !st.equals("")) {
                    words.add(st);
                    st = ("");
                }
    
                if(s >= 'a' && s <= 'z' || s >= 'A' && s <= 'Z') {
                    st += s;
                }
            }
    

    这是您尝试做的更简单的版本。

        public static List<String> getWords(String content) {
            return Arrays
                    .stream(content.split(" "))
                    .filter(f -> f.matches("^[a-zA-Z]+"))
                    .collect(Collectors.toList());
        }
    

    【讨论】:

    • 1.第一种方法是缺少返回语句并关闭} 2。第一种方法不检查句子中的最后一个字符是否为字母,因此任何字符都附加到最后一个单词。 3. simpler 版本会丢弃任何以散列 # 开头的单词,这可能对解析 Twitter 帖子至关重要。
    【解决方案3】:

    我认为有一个更好的方法可以通过使用字符串的split 方法来做到这一点。你可以这样做:

    public static List<String> getWords() {
        return Arrays.asList(content.split(" "));
    }
    

    如果你想删除推文的#,只需使用replace 方法,如下所示:

    public static List<String> getWords() {
        return Arrays.asList((content.replace("#","")).split(" "));
    }
    

    【讨论】:

    • Type mismatch: cannot convert from List&lt;String&gt; to ArrayList&lt;String&gt;Cannot invoke replace(String, String) on the array type String[]
    • 谢谢你,你是对的!我修好了它。第一个错误是因为 Arrays.asList 返回 List&lt;&gt; 而不是 ArrayList&lt;&gt; 我认为,这应该只能通过更改预期的函数返回来解决。第二个是因为.replace()是在.split()之后创建的!
    【解决方案4】:

    您正在跳过添加循环中的最后一个元素。下面可以解决问题:

    public ArrayList<String> getWords() {
            ArrayList<String> words = new ArrayList();
            String st = "";
            for(int i = 0; i < content.length(); ++i) {
                char s = content.charAt(i);
    
                if(s == ' ' && !st.equals("")) {
                    words.add(st);
                    st = ("");
                }
                if(s >= 'a' && s <= 'z' || s >= 'A' && s <= 'Z') {
                    st += s;
                }
    
                // This help to add last element in the list
                if (i == content.length()-1){
                    words.add(st);
                }
            }
    
            return words;
        }
    

    这是输出:

    这是所有代码。

    public class SGCtest {
    
        private String content;
    
        public ArrayList<String> getWords() {
            ArrayList<String> words = new ArrayList();
            String st = "";
            for(int i = 0; i < content.length(); ++i) {
                char s = content.charAt(i);
    
                if(s == ' ' && !st.equals("")) {
                    words.add(st);
                    st = ("");
                }
                if(s >= 'a' && s <= 'z' || s >= 'A' && s <= 'Z') {
                    st += s;
                }
    
                // This help to add last element in the list
                if (i == content.length()-1){
                    words.add(st);
                }
            }
    
            return words;
        }
    
    
    
        public static void main(String[] args) {
    
            SGCtest a = new SGCtest();
            a.content="i love my job #winning";
            System.out.println(" Printing the input string: "+a.content);
            ArrayList <String> bb =a.getWords();
            System.out.println(" Printing List: "+bb);
    
        }
    }
    

    【讨论】:

      【解决方案5】:

      这行代码删除了字符串中的所有非字母并返回单词列表:

          List words = Arrays.asList(content.replaceAll("[^a-zA-Z\\s]", "").split("\\s+"));
      

      首先,replaceAll 方法删除字符串中所有非字母或空格的字符。然后split方法用空格分割字符串,将所有单词放入一个数组中,再通过asList方法转换成List。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-03
        • 1970-01-01
        • 2017-07-02
        • 2019-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多