6道String練習題,你會做嗎?
前言
String字串在我們開發中非常高頻出現的一種資料結構,我這裡準備了幾道小題,不管你是初學者還是專家,都可以試試是否可以很容易的解決下面幾道題,如果你有更好的解決辦法,歡迎在評論去交流!
如何不使用Java內建方法反轉一個字串?
寫一個java程式檢查兩個字串是異位詞?【異位詞是指相同字元不同位置】
判斷一個字串中的所有字元是否只出現一次?
如何從字串中找到重複的字元?
找到字串的所有子字串?
找出一個輸入字串的所有排列可能?
再開始看下面的解法前不妨自己先想一想這幾道題都應該怎麼解決,然後看看下面的方法是不是和你想的一致,如果你的方法更好,歡迎在評論區留言。
如何不使用Java內建方法反轉一個字串?
解決這個問題有三種方式:
使用迴圈
使用遞迴
使用StringBuilder、StringBuffer
使用for迴圈
思路:
宣告一個空String變數,用來儲存最終反轉的字串;
使用for迴圈遍歷要反轉的字串,從最後一個位置到第0個位置;
在遍歷時將字元新增到宣告的空String變數上。
public class ReverseStringForMain { public static void main(String[] args) { String blogName = “小黑說Java”; String reverse = “”; for (int i = blogName。length() - 1; i >= 0; i——) { reverse = reverse + blogName。charAt(i);
} System。out。println(“Reverse of 小黑說Java is: ” + reverse);
}
}
使用遞迴
思路:
如果字串長度為1,則反轉結果為該字串本身;
如果字串長度大於1,則反轉結果為該字串的最後一個字元加剩餘字串的反轉結果。
public class ReverseStringRecursive { public static void main(String[] args) {
ReverseStringRecursive rsr = new ReverseStringRecursive(); String blogName = “小黑說Java”; String reverse = rsr。recursiveReverse(blogName);
System。out。println(“Reverse of 小黑說Java is:” + reverse);
}
public String recursiveReverse(String orig) { if (orig。length() == 1){ return orig;
}else{ return orig。charAt(orig。length() - 1) +
recursiveReverse(orig。substring(0, orig。length() - 1));
}
}
}
使用StringBuffer
使用StringBuffer的reverse方法,同樣可以實現字串的反轉功能。
public class StringBufferReverse { public static void main(String[] args) {
String blogName = “小黑說Java”;
StringBuffer sb = new StringBuffer(blogName);
System。out。println(“Reverse of 小黑說Java is:” + sb。reverse());
}
}
寫一個java程式檢查兩個字串是異位詞?
說明:異位詞是指兩個單詞有相同的字母,但是順序不同,如: Angel 和Angle。
這道題有多種解決方式:
使用String類的方法
使用Arrays。sort()
使用計數陣列
使用Guava的Multiset
使用String類方法
思路:
建立一個方法,接收兩個字串變數,用來判斷是否是異位詞;
迭代第一個String單詞,並使用charAt()方法從中獲得char c;
如果第二個String單詞的indexOf(c)的值等於-1,那麼兩個字串不是字謎;
如果第二個String單詞的indexOf(c)的值不等於-1,那麼從第二個單詞中刪除字元c;
如果第二個String單詞最後是個空字串,則代表兩個單詞是異位詞。
public class StringAnagramMain {
public static void main(String[] args) {
String word = “小黑說Java”;
String anagram = “小黑說JAVA”;
System。out。println(“小黑說Java and 小黑說JAVA are anagrams :” + isAnagramUsingStringMethods(word, anagram));
}
public static boolean isAnagramUsingStringMethods(String word, String anagram) { if (word。length() != anagram。length()) return false; for (int i = 0; i < word。length(); i++) { char c = word。charAt(i); int index = anagram。indexOf(c); if (index != -1) {
anagram = anagram。substring(0, index)
+ anagram。substring(index + 1, anagram。length());
} else{ return false;
}
} return anagram。isEmpty();
}
}
使用Arrays。sort()
思路:直接對兩個字串排序,如果排序之後兩個字串相等,則表示兩個字串是異位詞。
public class AnagramUsingSort {
public static void main(String[] args) { String word = “小黑說Java”; String anagram = “小黑說JAVA”;
System。out。println(“小黑說Java and 小黑說JAVA are anagrams :” + isAnagramUsingArraySort(word, anagram));
}
public static boolean isAnagramUsingArraySort(String word, String anagram) { String sortedWord = sortChars(word); String sortedAnagram = sortChars(anagram); return sortedWord。equals(sortedAnagram);
}
public static String sortChars(String word) {
char[] wordArr = word。toLowerCase()。toCharArray();
Arrays。sort(wordArr); return String。valueOf(wordArr);
}
}
使用計數陣列
思路:
如果兩個字串長度不同,則不是異位詞;
建立一個長度為256的陣列;
迭代第一個字串str1;
在每次迭代中,我們遞增第一個String str1的計數,遞減第二個String str2的計數;
如果任何字元的count在末尾不為0,則表示兩個string不是字謎。
這種方法的時間複雜度是O(n),但它需要額外的空間計數陣列。
public class AnagramCountingMain {
public static void main(String args[])
{ boolean isAnagram = isAnagram(“Angle”,“Angel”);
System。out。println(“Are Angle and Angel anangrams: ”+isAnagram);
}
public static boolean isAnagram(String str1, String str2) { if (str1。length() != str2。length()) { return false;
} int count[] = new int[256]; for (int i = 0; i < str1。length(); i++) {
count[str1。charAt(i)]++;
count[str2。charAt(i)]——;
} for (int i = 0; i < 256; i++) { if (count[i] != 0) { return false;
}
} return true;
}
}
使用Guava的Multiset
如果您喜歡使用Guava庫,那可以使用MultiSet來檢查兩個String是否為異位詞。
MultiSet允許每個元素出現多次,並記錄每個元素的計數。
當然這種方式需要在pom。xml新增Guava依賴。
程式碼如下:
import com。google。common。collect。HashMultiset;
import com。google。common。collect。Multiset;
public class AnagramMultiSet {
public static void main(String args[])
{
boolean isAnagram = isAnagramMultiset(“Angle”,“Angel”);
System。out。println(“Are Angle and Angel anangrams: ”+isAnagram);
}
public static boolean isAnagramMultiset(String str1, String str2) { if (str1。length() != str2。length()) { return false;
}
Multiset
Multiset
ms1。add(str1。charAt(i));
ms2。add(str2。charAt(i));
} return ms1。equals(ms2);
}
}
判斷一個字串中的所有字元是否只出現一次?
說明:比如Apple單詞中字元p出現多次,所以不符合;world中所有單詞都只出現一次,所以符合。
這道題有以下幾種解決方法:
使用HashSet
使用indexOf和lastIndexOf方法
使用字元的ascii值
使用HashSet
依賴於HashSet的add()方法,如果已存在的元素會返回false。
步驟:
遍歷每個字元,新增到HashSet;
如果HashSet的add方法返回false,那麼它不是所有的唯一字元。
public class StringAllUniqueCharMain {
public static void main(String[] args) {
System。out。println(“Apple has all unique chars :”+ hasAllUniqueChars(“apple”));
System。out。println(“index has all unique chars :”+ hasAllUniqueChars(“index”));
System。out。println(“world has all unique chars :”+ hasAllUniqueChars(“world”));
}
public static boolean hasAllUniqueChars (String word) {
HashSet alphaSet=new HashSet(); for(int index=0;index < word。length(); index ++) { char c =word。charAt(index); if(!alphaSet。add(c)) return false;
} return true;
}
}
使用indexOf和lastIndexOf方法
思路:如果indexOf和lastIndexOf對字元返回相同的值,則在該字串中不會重複。
public class StringAllUniqueCharMain {
public static void main(String[] args) {
System。out。println(“Apple has all unique chars : ”+ hasAllUniqueChars(“apple”));
System。out。println(“index has all unique chars : ”+ hasAllUniqueChars(“index”));
System。out。println(“world has all unique chars : ”+ hasAllUniqueChars(“world”));
}
public static boolean hasAllUniqueChars (String word) { for(int index=0;index < word。length(); index ++) { char c =word。charAt(index); if(word。indexOf(c)!=word。lastIndexOf(c)) return false;
} return true;
}
}
使用字元的ascii值
這個方法是最高效的。
思路:
建立一個長度為26的布林陣列;
將char轉換為大寫並獲取其ascii值;
將64減去ascii值以獲得0到25之間的索引;
如果字元不重複,則布林陣列中應該有false;
public class StringAllUniqueCharMain {
public static void main(String[] args) {
System。out。println(“Apple has all unique chars : ”+ hasAllUniqueChars(“apple”));
System。out。println(“index has all unique chars : ”+ hasAllUniqueChars(“index”));
System。out。println(“world has all unique chars : ”+ hasAllUniqueChars(“world”));
}
public static boolean hasAllUniqueChars (String word) {
boolean[] charMap = new boolean[26]; for(int index=0;index < word。length(); index ++) { // we are substracting char‘s ascii value to 64, so we get all index
// from 0 to 25。
int asciiCode = (int) word。toUpperCase()。charAt(index) - 64; if(!charMap[asciiCode])
charMap[asciiCode] = true; else
return false;
} return true;
}
}
如何從字串中找到重複的字元?
思路:
建立一個HashMap,建立一個HashMap,字串字元將作為key插入,其計數作為value插入;
如果HashMap已經包含char,則將其計數增加1,否則將char放入HashMap中;
如果Char的值大於1,這意味著它是該字串中的重複字元。
import java。util。HashMap;public class StringFindDuplicatesMain { public static void main(String[] args) { String str = “juejin。com ”; HashMap
char c = str。charAt(i); if (charCountMap。containsKey(c)) {
charCountMap。put(c, charCountMap。get(c) + 1);
} else {
charCountMap。put(c, 1);
}
} for (Character c : charCountMap。keySet()) { if (charCountMap。get(c) > 1) System。out。println(“duplicate character : ” + c + “ ====== ” + “ count : ” + charCountMap。get(c));
}
}
}
找到字串的所有子字串?
例如:如果輸入是abb,那麼輸出應該是a, b, b, ab, bb, abb
思路:使用String類的subString方法來查詢所有subString。
class SubstringsOfStringMain{ public static void main(String args[]){
String str=“abbc”;
System。out。println(“All substring of abbc are:”); for (int i = 0; i < str。length(); i++) { for (int j = i+1; j <= str。length(); j++) {
System。out。println(str。substring(i,j));
}
}
}
}
這個解決辦法的時間複雜度為O(n^3)。因為我們有兩個迴圈而且String的子字串方法的時間複雜度是O(n)
如果想找到String的所有不同的子字串,那麼需要使用HashSet來刪除重複的字串。
找出一個輸入字串的所有排列可能?
比如:輸入“AB”,輸出[“AB”,“BA”],輸入“ABC”,輸出[“ABC”,“ACB”,“BAC”,“BCA”,“CBA”,“CAB”]。
思路:
取出String的第一個字元,遞迴輸入剩餘String的排列的不同位置;
假設輸入String為ABC,取出第一個字元“A”;
從BC中取出B,將剩餘字串“C”遞迴輸入;
String長度為1時,返回,所以返回“C”;
將取出的“B”分別插入到遞迴返回結果的字串的每一個位置;
這時得到BC,CB,返回;
將取出的字元“A”分別插入返回結果的字串的每一個位置;
這時得到[ABC,BAC,BCA]和[ACB,CAB,CBA];
最終返回結果就是ABC的所有排序。
import java。util。HashSet;import java。util。Set;public class PermutationOfStringJava { public static void main(String[] args) {
Set
System。out。println(“Permutations of String ABC are:”); for (String str : set) {
System。out。println(str);
}
} public static Set
Set
permutationSet。add(str); return permutationSet;
}
char c = str。charAt(0); String rem = str。substring(1);
Set
permutationSet。add(permutation);
}
} return permutationSet;
} public static String insertFirstCharAtDiffPlaces(String perm, char firstChar, int index) { return perm。substring(0, index) + firstChar + perm。substring(index);
}
}
小結
以上就是本期的所有內容,怎麼樣,這些方法你都想到了嗎?如果你有更好的方法歡迎留言交流。
如果對你有幫助,點個贊是對我最大的鼓勵。