打印字符串 s 中字母按字母顺序出现的最长子串。

huangapple go评论86阅读模式
英文:

Write a program that prints the longest substring of s in which the letters ocur in alphabetical order

问题

我正在学习使用Java在线编程我了解表达式变量if语句循环静态方法数组switch语句等基础知识目前我在努力完成一个涉及编写方法的作业如果能得到一些帮助就太好了

下面是问题内容

**问题** 假设s是一个由小写字符组成的字符串编写一个程序打印出s中最长的满足字母按字母顺序排列的子字符串例如如果s = 'azcbobobegghakl'则你的程序应该打印出
```java
最长按字母顺序排列的子字符串是beggh

对于相同长度的子字符串,打印第一个子字符串。例如,如果s = 'abcbcd',则你的程序应该打印出

最长按字母顺序排列的子字符串是abc

以下是我目前的进展:

  • 将字符串s的字母作为单独的字符放入数组中
  • 使用for循环在数组中寻找最长按字母顺序排列的子字符串
static String problemThree(String s){
    for(int i = 0; i < s.length(); i++){
        
    }
    return s;
}

我不确定接下来该做什么,或者从哪里开始解决这个问题。


<details>
<summary>英文:</summary>

I&#39;m learning programming online with Java. I know expressions, variables, if statements, iterations, static methods, arrays, switches, and other basic things. I&#39;m currently struggling with an assignment involving writing methods right now, if I could get some help it would be great.

Here it is:

**Problem:** Assume s is a string of lower case characters. Write a program that prints the longest substring of s in which the letters occur in alphabetical order. For example, if s = &#39;azcbobobegghakl&#39;, then your program should print

Longest substring in alphabetical order is: beggh

In the case of times, print the first substring. For example, if s = &#39;abcbcd&#39;, then your program should print

Longest substring in alphabetical order is: abc

Here&#39;s what I have so far:
- put the letters of String s into an array as individual letters
- for loop scans through array for longest substring in alphabetical order

static String problemThree(String s){
for(int i = 0; i < s.length(); i++){

    }
    return s;
}
I&#39;m not sure what to do next or where to start with this problem.

</details>


# 答案1
**得分**: 0

For problem 2, 你可以从字符串的开头循环,并取子字符串 = 字符串的前3个字符,例如 azc,zcb,直到列表[length - 3](3 = “bob”的长度),每当子字符串等于“bob”时计数++。

For problem 3, 有一个占位符字符串 longestString = ""。
运行一个循环,对字符串中的每个字母进行定义,currentString = "",再运行另一个循环,从当前索引开始,如果按字母顺序追加字母到currentString(查找String.compareTo()),一旦达到不按字母顺序的字母,请检查currentString是否比longestString长 -> longestString = currentString。

<details>
<summary>英文:</summary>

For problem 2, you can loop from the start of the string and take  substring = 3 char of string e.g. azc, zcb until the list[length - 3] (3 = length of &quot;bob&quot;), and forever time substring.equals(&quot;bob&quot;) count ++.

For problem 3, have a placeholder String longestString = &quot;&quot;.
Run a for loop for each letter in the string, define currentString = &quot;&quot;, run another for loop from current index onward, append the letter to currentString if alphabetic order (look up for String.compareTo()), once you reach a letter not in alphabetic order, check if currentString is longer than longestString -&gt; longestString = currentString.


</details>



# 答案2
**得分**: 0

问题1的位置我不确定。

**问题2**:
这是一个完全错误的`switch`用法。你正在比较字符串`s`和`&quot;bob&quot;`是否相等。你错误的方法的一个替代方法是:
```java
if (&quot;bob&quot;.equals(s)) answer++;

越多的情况,你就越多地检查s的相等性。

正确的方法是使用String.indexOf(String, int)方法,如果存在,它将返回原始字符串中给定字符串的索引,从你指定的索引开始。

例如,

  1. &quot;abcbobabc&quot;.indexOf(&quot;bob&quot;, 0) 返回3。
  2. &quot;abcbobabc&quot;.indexOf(&quot;bob&quot;, 3) 返回3。
  3. &quot;abcbobabc&quot;.indexOf(&quot;bob&quot;, 5) 返回-1(找不到)。

提醒:第一个索引是0。

在找到第一个出现后,从下一个索引开始搜索,以便“第一个出现”将是下一个出现(如果存在的话),而不是我们找到的那个。

  1. &quot;bobob&quot;.indexOf(&quot;bob&quot;, 0) 返回0。
  2. &quot;bobob&quot;.indexOf(&quot;bob&quot;, 1) 返回2。
  3. &quot;bobob&quot;.indexOf(&quot;bob&quot;, 3) 返回-1。

但我们只想计数出现次数,不想返回出现的索引。因此,以下是代码:

if (s == null) return; // 防止空指针异常
int i = 0;
int count = 0;
while ((i = s.indexOf(&quot;bob&quot;, i)) != -1) {
    i++;
    count++;
}
return count;

问题3:Java没有直接扫描按字母顺序排列的子字符串的方法,因此您需要自己实现它,逐个字符扫描。

首先,任何两个字符的字母顺序只有在它们两者都是大写或小写时才能用不等号进行比较。

String longest = &quot;&quot;;
StringBuilder builder = new StringBuilder();
// 用于存储按字母顺序排列的字符串

for (int i = 0; i &lt; s.length(); i++) {
    char c = s.charAt(i); // 访问给定字符串中索引i处的字符。
    int length = builder.length();
    if (length == 0 /* 没有连续字符 */ 
        || Character.toLowerCase(builder.charAt(length - 1)) &lt;= Character.toLowerCase(c)
        /* 有连续字符,并且新字符的字母顺序大于最后一个字符,例如z大于a */) {
        /* 开始或继续连续字符 */
        builder.append(c);
    } else {
        /* 停止连续字符 */
        if (length &gt; longest.length()) {
            /* 新的连续字符比上一个长,因此替换它 */
            longest = builder.toString();
        }
        /* 无论连续字符是否足够长,都重置连续字符 */
        builder = new StringBuilder();
    }
}
return longest;

基本上,整个代码是这样的:

  1. 遍历所有字符。
  2. 继续添加按字母顺序排列的字符到字符串构建器中。
  3. 如果下一个字符不遵循顺序,停止连续字符。
  4. 查看由构建器构建的字符串是否比上一个字符串长。
英文:

I wonder where Problem 1 is.

Problem 2:
That is a completely wrong usage of switch. What you are doing is to compare string s with &quot;bob&quot; and see if they are equal. An alternative of your wrong approach is

if (&quot;bob&quot;.equals(s)) answer++;

The more cases, the more strings you are checking equality between s.

A correct approach is to make use of the String.indexOf(String, int) method, which returns you the index of the given string in the original string, if exists, starting at the index you specified.

For example,

  1. &quot;abcbobabc&quot;.indexOf(&quot;bob&quot;, 0) returns 3.
  2. &quot;abcbobabc&quot;.indexOf(&quot;bob&quot;, 3) returns 3.
  3. &quot;abcbobabc&quot;.indexOf(&quot;bob&quot;, 5) returns -1. (cannot find)

Reminder: the first index is 0.

After finding the first appearance, start searching from the next index so the "first appearance" will be the next one, if exists, instead of the one we found.

  1. &quot;bobob&quot;.indexOf(&quot;bob&quot;, 0) returns 0.
  2. &quot;bobob&quot;.indexOf(&quot;bob&quot;, 1) returns 2.
  3. &quot;bobob&quot;.indexOf(&quot;bob&quot;, 3) returns -1.

But we only want to count to appearance, not to return the indices of appearance. Hence, here is the code:

if (s == null) return; // prevent NullPointerException
int i = 0;
int count = 0;
while ((i = s.indexOf(&quot;bob&quot;, i)) != -1) {
    i++;
    count++;
}
return count;

Problem 3: Java does not have a method to directly scan for substrings in alphabetical order, so you will need to implement it yourself, by scanning character by character.

Firstly, the alphabetical order of any two characters can be compared with the inequality sign, only if both are together either upper case or lower case.

String longest = &quot;&quot;;
StringBuilder builder = new StringBuilder();
// for storing character streak in alphabetical order

for (int i = 0; i &lt; s.length(); i++) {
    char c = s.charAt(i); // Access the character at index i in the string given.
    int length = builder.length();
    if (length == 0 /* no streak */ 
        || Character.toLowerCase(builder.charAt(length - 1)) &lt;= Character.toLowerCase(c)
        /* has streak, and the new character has alphabetical order greater than 
the last one e.g. z greater than a */) {
        /* starts or continues the streak */
        builder.append(c);
    } else {
        /* stops the streak */
        if (length &gt; longest.length()) {
            /* new streak is higher than the last one, so replace it */
            longest = builder.toString();
        }
        /* either streak is not high enough or not, resets the streak */
        builder = new StringBuilder();
    }
}
return longest;

Basically the entire code is to

  1. Loop through all characters
  2. Keep adding characters that are in alphabetical order to the string builder
  3. If the next character does not follow the order, stop the streak
  4. See if the string built by the builder is longer than the last one

答案3

得分: 0

for problem 2 I'd personally save an index i and increment s.length() times, substring at i, checking whether substring begins with "bob".

for problem 3 save an index i and increment s.length() times, substring at i, save an index j and increment substring.length() times, save a char last, comparing substring.charAt(j) to the last character, if it occurs later in the alphabet than the last character or they are the same append the character to a String built and update the last character, finally if built.length() > longest.length() update longest to built

private static int problemTwo() {
    String s = "azcbobobegghakl";
    int count = 0;

    for (int i = 0; i < s.length(); i++) {
        if (s.substring(i).startsWith("bob")) {
            count++;
        }
    }

    return count;
}

private static String problemThree() {
    String s = "azcbobobegghakl",
            longest = "";

    // Increment i s.length() times, i determining how far into the string we start at e.g. if i is 5 substring will be "bobegghakl"
    for (int i = 0; i < s.length(); i++) {
        String substring = s.substring(i),
                built = "";
        char last = 0;

        // Increment j substring.length() times
        for (int j = 0; j < substring.length(); j++) {
            char c = substring.charAt(j);

            // If the last character occurs earlier in the alphabet or the same as the current character, append it to the built string, and update the last character to be the current
            if (last <= c) {
                built = built.concat(Character.toString(c));
                last = c;
            } else {
                // Break out of the for loop if the current character occurs earlier in the alphabet than the last
                break;
            }
        }
        
        if (built.length() > longest.length()) {
            longest = built;
        }
    }

    return longest;
}
英文:

for problem 2 I'd personally save an index i and increment s.length() times, substring at i, checking whether substring begins with "bob".

for problem 3 save an index i and increment s.length() times, substring at i, save an index j and increment substring.length() times, save a char last, comparing substring.charAt(j) to the last character, if it occurs later in the alphabet than the last character or they are the same append the character to a String built and update the last character, finally if built.length() > longest.length() update longest to built

    private static int problemTwo() {
String s = &quot;azcbobobegghakl&quot;;
int count = 0;
for (int i = 0; i &lt; s.length(); i++) {
if (s.substring(i).startsWith(&quot;bob&quot;)) {
count++;
}
}
return count;
}
private static String problemThree() {
String s = &quot;azcbobobegghakl&quot;,
longest = &quot;&quot;;
// Increment i s.length() times, i determining how far into the string we start at e.g. if i is 5 substring will be &quot;bobegghakl&quot;
for (int i = 0; i &lt; s.length(); i++) {
String substring = s.substring(i),
built = &quot;&quot;;
char last = 0;
// Increment j substring.length() times
for (int j = 0; j &lt; substring.length(); j++) {
char c = substring.charAt(j);
// If the last character occurs earlier in the alphabet or the same as the current character, append it to the built string, and update the last character to be the current
if (last &lt;= c) {
built = built.concat(Character.toString(c));
last = c;
} else {
// Break out of the for loop if the current character occurs earlier in the alphabet than the last
break;
}
}
if (built.length() &gt; longest.length()) {
longest = built;
}
}
return longest;
}

huangapple
  • 本文由 发表于 2020年8月11日 15:47:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63353747.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定