21天刷題計劃之2.2—小易喜歡的單詞(Java語言描述)
題目描述:
小易喜歡的單詞具有以下特性:
1.單詞每個字母都是大寫字母
2.單詞沒有連續相等的字母
3.單詞沒有形如“xyxy”(這裡的x,y指的都是字母,並且可以相同)這樣的子序列,子序列可能不連續。
例如:
小易不喜歡"ABBA",因為這裡有兩個連續的’B’
小易不喜歡"THETXH",因為這裡包含子序列"THTH"
小易不喜歡"ABACADA",因為這裡包含子序列"AAAA"
小易喜歡"A","ABA"和"ABCBA"這些單詞
給你一個單詞,你要回答小易是否會喜歡這個單詞(只要不是不喜歡,就是喜歡)。
輸入描述:
輸入為一個字串,都由大寫字母組成,長度小於100
輸出描述:
如果小易喜歡輸出"Likes",不喜歡輸出"Dislikes"
示例1:
輸入
AAA
輸出
Dislikes
題意分析:
本題的考察重點如下:
1,判斷輸入的是否為大寫字母。
2,判斷輸入的字串中是否存在連續相等的字元。
3,按照需求是存在連續的形如xyxy的子串,且可以不連續。其實就是判斷字串中是否有兩個字元出現以同樣的先後順序出現兩次。
本題的關鍵點就在第三條:如何確定連續的子串。
參考某位大神的思路
1,2的判斷就比較常規和容易了,看程式碼便一目瞭然。
下面重點講解第三點的判斷:因為兩者連續且相等的情況第二個標準其實已經做出了判定。對於形如ABAB的子串,我們需要對整個字串進行遍歷,該字串可能出現在開頭,也有可能出現在結尾。所以第一個字元A遍歷的區間位於0-String.length-3之間。這時,我們需要找到與之相同的字元出現的位置,根據判斷我們可以確定第二個字元A的存在區間為2-String.length-1的位置區間上。這時候重點來了,確定了第二個A的位置,我們取出第一個A到第二個A之間的子串S,然後判斷第二個A之後是否有字元包含在S中,如果有,則說明ABAB是存在的,所以輸出不喜歡。
程式碼實現如下:
import java.util.Scanner; public class Test2_2 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); while(scan.hasNext()){ String str = scan.next(); boolean b = isLike(str); System.out.println(result(b)); } scan.close(); } public static boolean isLike(String str) { char[] ch = str.toCharArray(); boolean flag = true; //判斷是否為大寫的字母。 for(int i = 0; i<ch.length;i++){ if(ch[i]>'Z'||ch[i]<'A') flag = false; } //判斷是否有連續的字元。 for(int i = 0;i<ch.length-1;i++){ if(ch[i]==ch[i+1]) flag = false; } require:for(int i = 0;i<ch.length-3;i++){//第一次迴圈字元A存在的區間 for(int j = i+2;j<ch.length-1;j++){//第二次迴圈字元A存在的區間。 if(ch[i]==ch[j]){//找到出現兩次的字元。 for(int k = j+1; k<ch.length;k++){//第二種迴圈字元B第二次存在的區間。 //判斷首先兩次出現的字元A中間是否包含第二種迴圈字元B。 if(str.substring(i+1, j).contains(String.valueOf(ch[k]))){ flag = false; break require; } } } } } return flag; } //判斷喜歡還是不喜歡。 public static String result(boolean b) { if(b) return "Likes"; else return "Dislikes"; } }
可能描述上有些不對的地方,希望大家批評指正。其實熟悉正則表示式之後,對於此類的字串問題應用正則將會十分簡單,由於本人學藝不精,正則好多記不住,所以就沒想到用正則來解決本題。