【问题标题】:Rearrange words in string in alphabetical order按字母顺序重新排列字符串中的单词
【发布时间】:2021-08-07 04:16:54
【问题描述】:

我正在尝试重新排列任何给定字符串中的单词(20 个单词或更少)。我遇到了这个问题,因为我无法打印字符串中的最后一个单词。我尝试修改循环范围,但无法解决问题。

public class ListString {
    String[] list = new String[20];
    int n = 0;

    public void read() {
        Scanner in = new Scanner(System.in);
        System.out.println("Please enter the sentence");
        String s = in.nextLine();
        String temp = "";
        for (int i = 0; i < s.length(); i++)
        {
            char ch = s.charAt(i);
            if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))  // range from a to z
                temp = temp + ch;
            else 
            {
                if (temp.length() > 0)
                {
                    list[n] = temp;
                    n++;
                    temp = "";
                }
            }
        }
    }

    public void print() {
        System.out.print(list[0]);          
        for (int i = 0; i < n; i++)
            System.out.print(" " + list[i]);          
        System.out.println(" ");
    }

    public void sort() {
        for (int i = 0; i < n; i++) { 
            String key = list[i]; 
            int j = i - 1; 
            while (j >= 0 && (list[j].compareToIgnoreCase(key) > 0)) 
            { 
                list[j + 1] = list[j]; 
                j = j - 1; 
            } 
            list[j + 1] = key; 
        } 
    }  
}

【问题讨论】:

    标签: java arrays string


    【解决方案1】:

    当您点击字符串末尾并且 temp 不为空时,就会发生这种情况。要修复它,您可以在循环后添加相同的 if 语句:

    for(int i = 0; i < s.length(); i++) {
        char ch = s.charAt(i);
        if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
            temp = temp + ch;
        } else {
            if(temp.length() > 0) {
                list[n] = temp;
                n++;
                temp = "";
            }
        }
    }
    
    if(temp.length() > 0) {
        list[n] = temp;
        n++;
        temp = "";
    }
    

    您还需要将输出修复为不打印第一个单词两次:

    public void print() {
        for(int i = 0; i < n; i++) {
            System.out.print(list[i] + " ");
        }
        System.out.println();
    }
    

    修复前的输出:

    a b c d e f g h i j k l m n o p q r s t
    a a b c d e f g h i j k l m n o p q r s 
    

    修复后的输出:

    a b c d e f g h i j k l m n o p q r s t
    a b c d e f g h i j k l m n o p q r s t 
    

    更新:

    您也可以使用streams 一站式解决您的问题

    public void read() {
        Scanner in = new Scanner(System.in);
        System.out.println("Please enter the sentence");
        String s = in.nextLine();
    
        String[] list = Arrays.stream(s.split(" ")).limit(20).sorted().toArray(String[]::new);
    }
    

    它通过空格字符分割输入字符串,获取前 20 个单词,对它们进行排序并创建一个数组。

    输出:

    t s r q p o n m l k j i h g f e d c b a z z z z z
    a b c d e f g h i j k l m n o p q r s t 
    

    【讨论】:

    • read 方法变量 list 的流版本在其声明中缺少类型。
    【解决方案2】:

    您不需要显式处理字符串的结尾:通过使用指向单词开头和结尾的整数指针,您可以这样做:

    int start = 0;
    while (start < s.length()) {
      // Increment a start pointer until it points to the end of the string or the start of a word.
      while (start < s.length() && !isLetter(s.charAt(start))) {
        start++;
      }
    
      // Increment an end pointer until it points to the end of the string or a non-word character.
      int end = start;
      while (end < s.length() && isLetter(s.charAt(end))) {
        end++;
      }
    
      if (start == end) {
        // You reached the end of the string.
        break;
      }
    
      // Grab the portion of the string between start and end, this is a word.
      list[n++] = s.substring(start, end);
    
      // Set up the start pointer to point to the end of this word, for the next iteration.
      start = end;
    }
    

    其中isLetter(char) 是一种检查参数是否在A 和Z 之间(在任何一种情况下)的方法。

    我看到了这种方法的一种变体,它避免了内部 while 循环:我不太喜欢这种方法,因为我认为它读起来不太清楚;但它没有太多重复检查长度(我认为这段代码有效,没有尝试过):

    for (int start = 0, end = 0; start < s.length();) {
      if (!isLetter(s.charAt(start))) {
        start++;
        end = start;
      } else if (isLetter(s.charAt(end))) {
        end++;
    
        if (end >= s.length() || !isLetter(s.charAt(end))) {
          list[n++] = s.substring(start, end);
          start = end;
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      • 2015-05-07
      • 1970-01-01
      • 2018-03-30
      相关资源
      最近更新 更多