如何在Java中不使用String.split()方法将字符串拆分为单词?

5

我的老师要求我们将一句话分成单词,但不能使用String.split()。我已经使用Vector(我们还没学过)、while-循环和子字符串完成了任务。有没有其他方法可以实现这个功能?(最好不使用Vectors/ArrayLists)。


问题的确切陈述是什么?它只是列举了你不能使用什么吗?还有其他提示吗? - Tudor
5
不要养成使用Vector的习惯,它已被ArrayList取代。 - Marko Topolnik
2
如果你的老师要求这样做,那么他希望能够自己完成,而不是让别人替你完成。我认为他希望你使用String的indexOf(String, int)方法来完成某些任务。 - Flavio Cysne
@FlavioCysne 这是在测试中出现的问题。我在测试中使用了indexOf,但代码看起来很混乱。我正在寻找更简洁的解决方法。 - Leo Jiang
16个回答

13

我相信你的老师要求你自己处理字符串(不使用任何其他库来代替你)。请确认一下是否是这种情况——如果可以使用,有一些工具可以方便地进行字符串处理,例如StringTokenizer、Pattern和Scanner。

否则...

你需要一个单词分隔符列表(例如空格、制表符、句号等),然后遍历数组,逐个字符构建字符串,直到遇到单词分隔符为止。在找到完整的单词(即遇到单词分隔符字符)后,将其保存到变量中,并重置正在构建单词的变量,然后继续进行。


1
你其实不需要一个单词分隔符列表。你可以直接使用 Character.isWhitespace - trutheality
string.split() 允许您分离使用非空格字符界定的单词,因此实现一个分隔符列表是有意义的。 - A D
@trutheality,如果要分词括号、逗号或其他既不是空格也不是单词字符的字符串(可能取决于规范/任务书的编写方式),你会怎么做?测试 Character.isLetter 可能更容易/更好实现。 - user289086
@MichaelTurner 如果你使用 Character.isLetter,当你遇到数字时可能会出现问题,而且在你建议将 Character.isDigit 添加到混合中之前,should_stuff_like_this_be_separated?那么像 12,000.75 这样的带有小数点和千位分隔符的句子应该保留,但逗号和句号应该省略,对吧?我会根据任务的具体要求使用最合适的方法(这并不是非常具体)。使用字符列表比 Character.isWhitespace 更通用,但有时过于通用会导致过度杀伤力。 - trutheality
2
@trutheality提出了一个很好的观点,关于数字和“12,000.75”是分词字符串困难的美妙例子。这回到了规范/任务要求“需要什么?”的问题。 - user289086

4
逐个字符解析字符串,将每个字符复制到一个新的字符串中,并在遇到空格字符时停止。然后开始一个新的字符串,继续直到原始字符串的末尾。

3
你可以使用 java.util.StringTokenizer 来使用所需的分隔符拆分文本。默认分隔符为空格/制表符/换行符。
String myTextToBeSplit = "This is the text to be split into words.";  
StringTokenizer tokenizer = new StringTokenizer( myTextToBeSplit );  
while ( tokinizer.hasMoreTokens()) {  
    String word = tokinizer.nextToken();  
    System.out.println( word ); // word you are looking in  
}  

作为备选方案,您也可以使用 java.util.Scanner
Scanner s = new Scanner(myTextToBeSplit).useDelimiter("\\s");  
while( s.hasNext() ) {  
System.out.println(s.next());  
}  
s.close();  

2
import java.util.Arrays;
public class ReverseTheWords {

    public static void main(String[] args) {
        String s = "hello java how do you do";
        System.out.println(Arrays.toString(ReverseTheWords.split(s)));
    }

    public static String[] split(String s) {
        int count = 0;
        char[] c = s.toCharArray();

        for (int i = 0; i < c.length; i++) {
            if (c[i] == ' ') {
                count++;
            }
        }
        String temp = "";
        int k = 0;
        String[] rev = new String[count + 1];
        for (int i = 0; i < c.length; i++) {
            if (c[i] == ' ') {
                rev[k++] = temp;
                temp = "";
            } else
                temp = temp + c[i];
        }
        rev[k] = temp;
        return rev;
    }

}

当你遇到空格时,这个方法可以很好地分割字符串。 - vinay j

2

您可以使用java.util.Scanner。


1

在不使用Vector/List(也不手动重新实现它们的自我调整大小的能力)的情况下,您可以利用一个简单的观察结果:长度为N的字符串不能超过(N+1)/2个单词(在整数除法中)。您可以声明一个该大小的字符串数组,以与填充Vector相同的方式填充它,然后将结果复制到您找到的单词数量大小的数组中。

所以:

String[] mySplit( String in ){
    String[] bigArray = new String[ (in.length()+1)/2 ];

    int numWords = 0;
    // Populate bigArray with your while loop and keep
    // track of the number of words

    String[] result = new String[numWords];
    // Copy results from bigArray to result

    return result;
}

1
public class sha1 {
public static void main(String[] args) {
    String s = "hello java how do you do";
    System.out.println(Arrays.toString(sha1.split(s)));
}
public static String[] split(String s) {
    int count = 0;
    char[] c = s.toCharArray();

    for (int i = 0; i < c.length; i++) {
        if (c[i] == ' ') {
            count++;
        }
    }
    String temp = "";
    int k = 0;
    String[] rev = new String[count + 1];
    for (int i = c.length-1; i >= 0; i--) {
        if (c[i] == ' ') {
            rev[k++] = temp;
            temp = "";
        } else
            temp = temp + c[i];
    }
    rev[k] = temp;
    return rev;
}

}


1

1

或者使用一个“模式”(也称为正则表达式)来尝试匹配这些单词。


1
  • 使用带有ctor (String)的Scanner
  • 正则表达式和匹配
  • StringTokenizer
  • 逐个字符地进行迭代
  • 递归迭代

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接