Java演算法面試題(003) 如何檢查一個字串是另外一個字串的旋轉字串
宣告:本文為本博主翻譯,未經允許,嚴禁轉載!
簡介
編寫一個程式來檢查一個字串是否是另一個字串的旋轉字串是一個常見的編碼問題,你將在程式設計工作面試中看到。一個字串被認為是另一個字串的旋轉,如果它具有相同的長度,包含相同的字元,並且圍繞其中一個字元旋轉。例如,字串“bcda”是“abcd”的旋轉,但“bdca”不是字串“abcd”的旋轉。對這個有趣的問題最簡單的解決方案之一是首先檢查兩個字串是否具有相同的長度,如果不是一個字串不能是另一個字串的旋轉。如果它們的長度相同,那麼只需要通過連線第一個字串和自己來建立另一個字串,現在檢查第二個字串是否是這個連線字串的子字串,如果是,那麼第二個字串是第一個字串的旋轉。
您可能想知道,這個解決方案是如何工作的?那麼,你可以圍繞某個字元旋轉字串,如果你加入了字串本身,那麼它實際上包含了它自己的所有旋轉版本。因此,當您使用contains()方法檢查旋轉後的字串是此串聯字串的一部分時,如果是,則返回true,否則返回false。
讓我們用一個例子來理解這個,假設“JavaProgrammer”是第一個字串,“ProgrammerJava”是第二個字串。你可以圍繞從索引0開始的任何字元旋轉字串,即'J'到index=length-1,這是'r ”。
現在,如果將“JavaProgrammer”與自身連線起來,則會得到“JavaProgrammerJavaProgrammer”,現在您可以看到它包含第一個字串的每個可能的旋轉。這是一個非常好的解決方案,當我第一次瞭解它的時候,我和你現在一樣驚訝。
順便說一句,如果面試官會問你如何解決這個問題,而不使用字串連線,那麼你做什麼?我會告訴你如何在這篇文章中做到這一點。
問題
給定兩個字串s1和s2,你將如何檢查s1是否是s2的旋轉版本?
方案
正如我所說,解決這個問題有兩種方法,一是使用字串連線,二是不使用字串連線。
解決方案1的邏輯
下面是通過使用字串連線來檢查字串是否是另一個字串的旋轉的步驟:
1. 使用+運算子連線兩個字串s1和s1。如果你願意的話,你也可以使用StringBuffer或者StringBuilder,但是+看起來不錯,乾淨,而且在內部也使用StirngBuilder(見Effective Java)。
2. 通過使用contains()方法檢查連線版本中是否存在旋轉版本。
解決方案2的邏輯
下面是檢查一個給定的String s2是否是String s1的旋轉而不使用字串連線的步驟。
1. 檢查兩個字串的長度是否相同,如果不是,則不是旋轉。如果是,則繼續下一步。
2. 檢查兩個字串是否相等,如果是,則s2是s1的一個旋轉。如果不是,則轉到下一步。
3. 取第一個字串的第一個字元,並在第二個字串中找到索引。如果找不到,則不是旋轉,但是如果找到,繼續下一步。
4. 用找到的索引減去旋轉字串的長度以找到最終位置。
5. 檢查被旋轉的String的第一個字元是否與輸入String的最後位置的字元相同,並且input.substring(finalPos)等於rotate.substring(0,index)。
如果沒有限制,可以使用任何解決方案解決問題,但如果面試官不允許字串連線,則使用第二種解決方案。
Java程式碼實現
/**
* Java Program to check if one String is rotation of other. In this program, we
* will see two solution of this interesting problem, one by using String
* concatenation and other without using String concatenation.
*
* @author Javin
*
*/
public class RotateStringDemo {
/**
* Returns true if one string is rotation of another, nulls are not
* considered rotation of each other
*
* @param str
* @param rotated
* @return true if rotated is rotation of String str
*/
public static boolean isRotatedVersion(String str, String rotated) {
boolean isRotated = false;
if (str == null || rotated == null) {
return false;
} else if (str.length() != rotated.length()) {
isRotated = false;
} else {
String concatenated = str + str;
isRotated = concatenated.contains(rotated);
}
return isRotated;
}
/**
* Return true if rotated is rotation of input String
*
* @param input
* @param rotated
* @return true if one String is rotation of other
*/
public static boolean isRotated(String input, String rotated) {
if (input == null || rotated == null) {
return false;
} else if (input.length() != rotated.length()) {
return false;
}
int index = rotated.indexOf(input.charAt(0));
if (index > -1) {
if (input.equalsIgnoreCase(rotated)) {
return true;
}
int finalPos = rotated.length() - index;
return rotated.charAt(0) == input.charAt(finalPos)
&& input.substring(finalPos).equals(rotated.substring(0, index));
}
return false;
}
public static void main(String args[]) {
String test = "abcd";
String rotated = "dabc";
boolean isRotated = isRotatedVersion(test, rotated);
System.out.printf("Is '%s' is rotation of '%s' : %b %n", rotated, test, isRotated);
}
}
Junit測試
這裡是一些單元測試來驗證兩個版本的字串旋轉邏輯。這是使用JUnit 4庫編寫的,因此您需要將junit4.jar包含到您的類路徑中以執行這些測試。 @Test註釋用於建立測試方法,這些方法將由JUnit Runner執行。請參閱JUnit in Action以瞭解有關JUnit如何工作以及如何執行測試用例的更多資訊。
public class RotateStringDemoTest {
@Test
public void testIsRotatedVersion() {
assertTrue(isRotatedVersion("abc", "bca"));
assertTrue(isRotatedVersion("abc", "cab"));
assertFalse(isRotatedVersion("abc", "bac"));
assertFalse(isRotatedVersion("abc", null));
assertFalse(isRotatedVersion("abc", ""));
}
@Test
public void testisRotated() {
assertTrue(isRotated("1234", "2341"));
assertTrue(isRotated("1234", "3412"));
assertTrue(isRotated("1234", "4123"));
assertFalse(isRotated("1234", "23s41"));
assertFalse(isRotated("1234", null));
assertFalse(isRotated("1234", ""));
}
}
這是關於如何檢查兩個字串是否在Java中相互旋轉。最簡單的解決方案是隻連線原始和旋轉的字串,並檢查旋轉是否存在於大的連線字串中。這是一個了不起的解決方案,因為當你加入原始和旋轉的版本時,它包含了第一個字串的每一個可能的旋轉。如果給定的旋轉出現在串聯的字串中,那麼它肯定是給定字串的旋轉。
原文連結
2 Ways to check if A String is rotation of other in Java?
譯者註釋
方案2的處理其實還是有問題,它無法處理包含重複字串的情況,相應的實現可以修改如下:
public static boolean isRotated(String input, String rotated) {
if (input == null || rotated == null) {
return false;
} else if (input.length() != rotated.length()) {
return false;
}
int index = 0;
int finalPos = 0;
do {
index = rotated.indexOf(input.charAt(0), index);
if (index < 0) {
return false;
}
// if (input.equalsIgnoreCase(rotated)) {
// return true;
// }
finalPos = rotated.length() - index;
if (rotated.charAt(0) == input.charAt(finalPos)
&& input.substring(finalPos).equals(rotated.substring(0, index))) {
return true;
}
index += 1;
} while (index < input.length());
return false;
}
相關文章
- Javascript 是如何檢查一個存在的、非空的字串?JavaScript字串
- 字串相關演算法1-字串旋轉字串演算法
- 一個字串比較的題字串
- 旋轉字串字串
- JAVA面試題筆試題-查詢一個字串不重複最長的串(個人方法)Java面試題筆試字串
- (字串動態規劃)一個字串變成另一個字串的步驟數字串動態規劃
- java查詢字串裡與指定字串相同的個數Java字串
- 一個簡單的字串查詢程式字串
- Java演算法面試題(008) 字串反轉Java演算法面試題字串
- 判斷某一個字串是否存在另一個字串中字串
- Java演算法面試題(004) 實現一個演算法來確定一個字串是否具有所有唯一的字元Java演算法面試題字串字元
- java中排序一個字串陣列Java排序字串陣列
- 檢測一個字串是否在jvm的常量池中字串JVM
- Python判斷一個檔案中的字串是否存在於另外一個檔案中Python字串
- 字串-面試題字串面試題
- iOS從0到1| OC 中如何檢查一個字串 string 是否包含另一個 stringiOS字串
- C++字串處理的一個例子:1.查詢一個字元在字串中第n次出現的位置。2分割字串C++字串字元
- 十個最常見的Java字串問題Java字串
- MySQL 查詢字串的個數MySql字串
- 如何判斷一個字串是否為純數字的問題,當然也可以判斷一個字串是否為純字母字串
- 進行一個字串演算法的總結字串演算法
- 微軟實現字串函式的一個BUG (轉)微軟字串函式
- JAVA字串轉日期或日期轉字串Java字串
- eval解析JSON字串的一個小問題JSON字串
- 建立一個字串分割的函式字串函式
- ASP中一個字串處理類(VBScript) (轉)字串
- 一道與 for 相關的字串面試題字串面試題
- 關於PHP字串的一道面試題PHP字串面試題
- 字串的一個操作(替換類似陣列字串中的項)字串陣列
- 身份證字串檢查字串
- LeetCode初級演算法之字串:387 字串中的第一個唯一字元LeetCode演算法字串字元
- 判斷一個字串是否包含一個子串的方法字串
- js如何判斷一個變數是數字還是數字字串JS變數字串
- iOS 擷取字串中兩個指定字串中間的字串iOS字串
- python怎麼查詢字串中是否包含某個字串Python字串
- js刪除字串的第一個字元JS字串字元
- python 小白求教一個字串顯示問題Python字串
- 一個有趣的問題: 如何用HashSet來儲存重複的字串?字串