【问题标题】:Find word in User Content without using .split() or StringTokenizer不使用 .split() 或 StringTokenizer 在用户内容中查找单词
【发布时间】:2019-10-25 17:13:31
【问题描述】:

我正在开发一个要求用户输入短语和整数的程序。该整数用于标识将从短语中返回的单词。例如,如果他们输入 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;

我想了很多关于如何处理中间部分的问题,我的想法是如果用户选择 numWord = 5,那么为了返回该句子中的第五个单词,我将需要使用“newPhrase .substring(第 4 个空格 +1,第 5 个空格)”。这就是我卡住的地方,因为我不知道如何开始,以及如何到达第四空间。

【问题讨论】:

  • 看看String.split()...这会让这件事变得更容易
  • 您在标题中声明不想使用split,但您没有给出原因。
  • 您好,很抱歉忘记说明原因。我不想使用 split 和 StringTokenizer 因为首先我还没有了解它们,而且我知道如果我使用它们会很容易。但是在我现在的初学者水平上,我想弄清楚是否有任何方法可以仅使用子字符串和循环来使它起作用。
  • 嗯,一个有效的句子将是例如No, it was 'no?', and not 'yes!' - ok?,现在结果将是 Noit was 'no?,' 等,您必须将 ' ,?!- 也视为空格,不是吗,并且连续覆盖多个空白?您可以使用here 中的正则表达式匹配器方法和此正则表达式来获取单个单词"[A-Za-z0-9]*"。您仍然会对you'd 之类的词有疑问,这是一个词,对吧?

标签: java if-statement java.util.scanner counter static-methods


【解决方案1】:
public static String combineString(String newPhrase, int newNum) {
     if(newNum<=0)
        return null;
     String word = "";
     String [] match = new String[newNum];

    int j =0;
    for(int i=0; i< newPhrase.length(); i++) {
        word = word + newPhrase.charAt(i);
        if(newPhrase.charAt(i) == ' ') { 
           match[j] = word;
           if(j+1 == newNum) {
              return word; // returns the specified word
           } 
           j++;
           word = "";    
       }
    } 
    return word; //returns last word
  }

此代码应该适合您。如果是这种情况,请接受答案。

【讨论】:

    【解决方案2】:

    如果你想达到非常低的水平,那么你可以低于subString,对单个字符进行操作。这样很容易跳过空白以外的其他字符。通过将正则表达式转换为有限状态自动机,这也是朝着执行正则表达式的方式迈出的一步。

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      相关资源
      最近更新 更多