Java 不使用.split()或StringTokenizer在用户内容中查找word

Java 不使用.split()或StringTokenizer在用户内容中查找word,java,if-statement,java.util.scanner,counter,static-methods,Java,If Statement,Java.util.scanner,Counter,Static Methods,我正在开发一个程序,要求用户输入一个短语和一个整数。整数用于标识将从短语返回的单词。例如,如果输入5,程序应将句子中的第五个单词返回给用户 System.out.println("Your word is: " +combineString(phrase,numWord)); 这是我到目前为止的工作,有一个主要的输出 public static String combineString(String newPhrase, int newNum) { int countWords = 0;

我正在开发一个程序,要求用户输入一个短语和一个整数。整数用于标识将从短语返回的单词。例如,如果输入5,程序应将句子中的第五个单词返回给用户

System.out.println("Your word is: " +combineString(phrase,numWord));
这是我到目前为止的工作,有一个主要的输出

public static String combineString(String newPhrase, int newNum) {
  int countWords = 0;
  String word = "";

  //words count. I'll +1 everytime using countWord the match the amount of words
  for(int i=0; i< newPhrase.length(); i++) {
     if(newPhrase.charAt(i) == ' ') {
        countWords++;             
     }
  }  

  //return the last word. Ex: 15 words in a phrase if user pick the 18th word it will return the 15th word.
  if(countWords+1 < newNum  || countWords+1 <= newNum) {
     word += newPhrase.substring(newPhrase.lastIndexOf(' ')+1, newPhrase.length()-1);
  }
  else if(newNum <=0) { //return null if the user pick 0 or less than 0
     word += null;   
  }           
  return word;
公共静态字符串组合字符串(字符串newPhrase,int newNum){
int countWords=0;
字串=”;
//字数计算。每次使用countWord时,我将+1匹配字数
for(int i=0;ipublicstaticstringcombinestring(stringnewphrase,intnewnum){
if(newNum
publicstaticstringcombinestring(stringnewphrase,intnewnum){

if(newNum如果你想去真正的低级别,那么你可以去低于
的子字符串
并对单个字符进行操作。这样很容易跳过空白以外的其他字符。这也是通过将正则表达式转换为有限状态自动机来执行正则表达式的一个步骤

enum ScanState {WHITESPACE, WORD}

private final static Set<Character> whitespace = new HashSet<>(Arrays.asList('"', ',', '.', '?', '!', '-', ';', ' '));

@Test
public void testTokenize() {
    char[] text = "No, it's been \"yes?\", and not \"no!\" - hasn't it?".toCharArray();
    List<String> expected = Arrays.asList("No", "it's", "been", "yes", "and", "not", "no", "hasn't", "it");
    assertEquals(expected, tokenize(text));
}

private List<String> tokenize(char[] text) {
    List<String> result = new ArrayList<String>();
    char[] word = new char[256];
    int maxLetter = 0;
    ScanState prevState = ScanState.WHITESPACE;

    for (char currentChar : text) {
        ScanState currState = whitespace.contains(currentChar) ? ScanState.WHITESPACE : ScanState.WORD;

        if (prevState == ScanState.WORD && currState == ScanState.WORD) {
            word[maxLetter++] = currentChar;
        }
        if (prevState == ScanState.WORD && currState == ScanState.WHITESPACE) {
            word[maxLetter++] = currentChar;
            result.add(String.valueOf(word, 0, maxLetter - 1));
        }
        if (prevState == ScanState.WHITESPACE && currState == ScanState.WORD) {
            maxLetter = 0;
            word[maxLetter++] = currentChar;
        }
        prevState = currState;
    }
    return result;
}
枚举扫描状态{空白,字}
private final static Set whitespace=new HashSet(Arrays.asList(“”、“、”、“、”、“?”、“!”、“-”、“;”、“));
@试验
公共void testTokenize(){
char[]text=“不,它一直是\“是的”\,而不是\“不”\-不是吗?”.toCharArray();
所需列表=数组。asList(“否”、“它是”、“曾经”、“是”、“和”、“不是”、“否”、“还没有”、“它”);
assertEquals(预期,标记化(文本));
}
私有列表标记化(字符[]文本){
列表结果=新建ArrayList();
字符[]字=新字符[256];
int maxLetter=0;
ScanState prevState=ScanState.WHITESPACE;
for(字符当前字符:文本){
ScanState currState=whitespace.contains(currentChar)?ScanState.whitespace:ScanState.WORD;
if(prevState==ScanState.WORD&&currState==ScanState.WORD){
word[maxLetter++]=currentChar;
}
if(prevState==ScanState.WORD&&currState==ScanState.WHITESPACE){
word[maxLetter++]=currentChar;
add(String.valueOf(word,0,maxLetter-1));
}
if(prevState==ScanState.WHITESPACE&&currState==ScanState.WORD){
maxLetter=0;
word[maxLetter++]=currentChar;
}
prevState=当前状态;
}
返回结果;
}

如果你想达到真正的低级别,那么你可以低于
子字符串
并对单个字符进行操作。这样就很容易跳过除空白以外的其他字符。这也是通过将正则表达式转换为有限状态自动机来执行正则表达式的一个步骤

enum ScanState {WHITESPACE, WORD}

private final static Set<Character> whitespace = new HashSet<>(Arrays.asList('"', ',', '.', '?', '!', '-', ';', ' '));

@Test
public void testTokenize() {
    char[] text = "No, it's been \"yes?\", and not \"no!\" - hasn't it?".toCharArray();
    List<String> expected = Arrays.asList("No", "it's", "been", "yes", "and", "not", "no", "hasn't", "it");
    assertEquals(expected, tokenize(text));
}

private List<String> tokenize(char[] text) {
    List<String> result = new ArrayList<String>();
    char[] word = new char[256];
    int maxLetter = 0;
    ScanState prevState = ScanState.WHITESPACE;

    for (char currentChar : text) {
        ScanState currState = whitespace.contains(currentChar) ? ScanState.WHITESPACE : ScanState.WORD;

        if (prevState == ScanState.WORD && currState == ScanState.WORD) {
            word[maxLetter++] = currentChar;
        }
        if (prevState == ScanState.WORD && currState == ScanState.WHITESPACE) {
            word[maxLetter++] = currentChar;
            result.add(String.valueOf(word, 0, maxLetter - 1));
        }
        if (prevState == ScanState.WHITESPACE && currState == ScanState.WORD) {
            maxLetter = 0;
            word[maxLetter++] = currentChar;
        }
        prevState = currState;
    }
    return result;
}
枚举扫描状态{空白,字}
private final static Set whitespace=new HashSet(Arrays.asList(“”、“、”、“、”、“?”、“!”、“-”、“;”、“));
@试验
公共void testTokenize(){
char[]text=“不,它一直是\“是的”\,而不是\“不”\-不是吗?”.toCharArray();
所需列表=数组。asList(“否”、“它是”、“曾经”、“是”、“和”、“不是”、“否”、“还没有”、“它”);
assertEquals(预期,标记化(文本));
}
私有列表标记化(字符[]文本){
列表结果=新建ArrayList();
字符[]字=新字符[256];
int maxLetter=0;
ScanState prevState=ScanState.WHITESPACE;
for(字符当前字符:文本){
ScanState currState=whitespace.contains(currentChar)?ScanState.whitespace:ScanState.WORD;
if(prevState==ScanState.WORD&&currState==ScanState.WORD){
word[maxLetter++]=currentChar;
}
if(prevState==ScanState.WORD&&currState==ScanState.WHITESPACE){
word[maxLetter++]=currentChar;
add(String.valueOf(word,0,maxLetter-1));
}
if(prevState==ScanState.WHITESPACE&&currState==ScanState.WORD){
maxLetter=0;
word[maxLetter++]=currentChar;
}
prevState=当前状态;
}
返回结果;
}

查看
String.split()
…如果你在标题中说你不想使用split,但你没有给出原因,这会让这更容易。嗨,很抱歉我忘了说明原因。我不想使用split和StringTokenizer,因为首先我还没有了解它们,我知道如果我使用它们会很容易。但是在我的水平上现在,对于初学者,我想知道是否有任何方法可以仅仅使用子字符串和循环来实现这一点。嗯,一个有效的句子应该是,例如,
No,它是“No”,而不是“yes!”-好吗?
,现在结果将是
No
它是
等等,你必须处理
,?!
>也可以作为空格,不是吗,并在一行中覆盖多个空格?您可以使用此正则表达式中的正则表达式匹配器方法来获取单个单词
“[a-Za-z0-9]*”
。您仍然会遇到类似
的问题,这是一个单词,对吗?查看
String.split()
…如果你在标题中说你不想使用split,但你没有给出原因,这会让这更容易。嗨,很抱歉我忘了说明原因。我不想使用split和StringTokenizer,因为首先我还没有了解它们,我知道如果我使用它们会很容易。但是在我的水平上现在,对于初学者,我想知道是否有任何方法可以仅仅使用子字符串和循环来实现这一点。嗯,一个有效的句子应该是,例如,
No,它是“No”,而不是“yes!”-好吗?
,现在结果将是
No
它是
等等,你必须处理
,?!
>也可以是空白,不是吗,并在一行中覆盖多个空格