我有一個序列,我正在嘗試撰寫一個程式來查找序列的第 n 項。
順序如下:
1、11、21、1211、111221、312211...
在這個序列中,每個術語都描述了前一個術語。例如,“1211”表示上一個詞;前一項是“21”,其中出現一次2,然后出現一次1 ( =1211)。要獲得第三項“21”,請查看第二項: 11. 有兩次出現的1給出了“21”。
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println( Main.num(n-1, "1"));
}
public static String num(int times, String x){
if(times == 0){
return x;
}else{
//System.out.println("meow");
String y = "" x.charAt(0);
int counter = 0;
for(int i = 1; i < x.length(); i ){
if(x.charAt(i) == x.charAt(i-1)){
counter ;
}else{
y = "" counter x.charAt(i-1);
counter = 0;
}
}
return num(times--, y);
}
//return "";
}
}
我的代碼使用遞回來查找第 n 項。但是,它給了我們錯誤:(
首先,我通過傳遞術語數-1(因為第一個術語已經給出)和第一個術語(1)來啟動方法“num”。
在方法 num 中,我們首先使用條件來建立基本情況(當您找到第 n 項時)。
如果基本情況為假,那么您將找到序列中的下一項。
uj5u.com熱心網友回復:
這是一個非常酷的序列!我喜歡它是基于英語而不是數學的,哈哈。
在您的解決方案中,代碼的遞回邏輯是正確的:找到每個術語后,您使用已知數字重復該方法并使用該元素找到下一個術語,并在確定第一個n元素時結束。您的基本情況也是正確的。
但是,您為確定序列中的項而開發的演算法是問題所在。
為了確定序列中的下一個元素,我們想要:
邏輯錯誤:
y為您的下一個元素創建一個空變數。但是,變數counter不應從 開始0。這是因為每個元素總是會出現至少1,所以我們應該初始化int counter = 1;遍歷
x. (您正確地完成了這一步)我們從 開始i = 1,因為我們將每個字符與前一個字符進行比較。如果當前字符等于前一個字符,我們
counter增加1.否則,我們
counter將被重復的字符連接到y。請記住,要重新初始化counter為1,而不是0。
技術錯誤:
- 一旦迭代結束
x,我們需要將 finalcounter和字符連接到y,因為用于最終字符的 else 陳述句將永遠不會在我們的 for 回圈中運行。
這是通過以下代碼完成的:y = "" counter x.charAt(x.length() - 1);
- 最后,當你進行遞回呼叫時,你應該做
--times而不是times--. 這兩個引數之間的區別在于,使用您的原始代碼,您是在遞減。這意味著在times方法呼叫之后 的值正在減小,此時我們希望將減小的值發送到方法中。為了解決這個問題,我們需要預先遞減,做--times.
import java.util.*;
class CoolSequence {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(num(n, "1"));
}
public static String num(int times, String x){
if(times == 0){
return x;
}
else{
String y = "";
int counter = 1;
for(int i = 1; i < x.length(); i ){
if(x.charAt(i) == x.charAt(i - 1)){
counter ;
}
else{
y = "" counter x.charAt(i - 1);
counter = 1;
}
}
y = "" counter x.charAt(x.length() - 1);
return num(--times, y);
}
}
}
測驗:
6
13112221
另一種方法是使用迭代方法:
import java.util.*;
class CoolSequence2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList<String> nums = new ArrayList<String>();
int n = scan.nextInt();
String val = "1";
for(int i = 0; i < n; i ){
String copy = val;
val = "";
while(!copy.equals("")){
char curr = copy.charAt(0);
int ind = 0;
int cons = 0;
while(ind < copy.length() && curr == copy.charAt(ind)){
cons = 1;
ind = 1;
}
val = String.valueOf(cons) copy.charAt(cons - 1);
copy = copy.substring(cons);
}
nums.add(val);
}
System.out.println(nums.get(nums.size() - 1));
}
}
6
13112221
在這種方法中,我們使用 for 回圈來遍歷n術語。為了確定每個元素,我們執行與您的邏輯類似的方法:
- 我們創建一個空字串 ,
val來保存新元素,并將當前元素存盤在copy. 我們也初始化一個cons,類似于你的counter. - 雖然
copy不是空的,但我們迭代copy并遞增cons,直到有一個元素不等于下一個元素。 - 發生這種情況時,我們會將
cons重復的元素連接到val,就像在您的代碼中一樣。然后,我們從中洗掉重復的元素copy并繼續該程序。 val我們添加to的新值nums,并不斷迭代n元素。
我希望這兩種解決問題的方法對您有所幫助!如果您有任何進一步的問題或澄清,請告訴我:)
uj5u.com熱心網友回復:
您可以使用Pattern反向參考。
正則運算式"(.)\\1*"匹配任何單個字符 ( "(.)") 和相同字符 ( ) 的零個或多個序列"\\1*"。"\\1"稱為反向參考,它參考括號 1 中的字串。
例如,它匹配111,22和1for 111221。
replaceAll()每次匹配時呼叫引數指定的 lambda 運算式。lambda 運算式接收 aMatchResult并回傳一個字串。匹配的字串被替換為結果。
本例中的 lambda 運算式連接匹配字串 ( match.group().length()) 的長度和第一個字符 ( match.group(1))。
static final Pattern SEQUENCE_OF_SAME_CHARACTER = Pattern.compile("(.)\\1*");
static String num(int times, String x) {
for (int i = 0; i < times; i)
x = SEQUENCE_OF_SAME_CHARACTER.matcher(x).replaceAll(
match -> match.group().length() match.group(1));
return x;
}
public static void main(String[] args) {
for (int i = 1; i <= 8; i)
System.out.print(num(i - 1, "1") " ");
}
輸出:
1 11 21 1211 111221 312211 13112221 1113213211
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/523492.html
標籤:爪哇递归序列
上一篇:理解968代碼的問題。二叉樹相機
