6道String練習題,你會做嗎?

前言

String字串在我們開發中非常高頻出現的一種資料結構,我這裡準備了幾道小題,不管你是初學者還是專家,都可以試試是否可以很容易的解決下面幾道題,如果你有更好的解決辦法,歡迎在評論去交流!

如何不使用Java內建方法反轉一個字串?

寫一個java程式檢查兩個字串是異位詞?【異位詞是指相同字元不同位置】

判斷一個字串中的所有字元是否只出現一次?

如何從字串中找到重複的字元?

找到字串的所有子字串?

找出一個輸入字串的所有排列可能?

再開始看下面的解法前不妨自己先想一想這幾道題都應該怎麼解決,然後看看下面的方法是不是和你想的一致,如果你的方法更好,歡迎在評論區留言。

6道String練習題,你會做嗎?

如何不使用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依賴。

com。google。guava

guava

27。1-jre

程式碼如下:

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 ms1 = HashMultiset。create();

Multiset ms2 = HashMultiset。create();        for (int i = 0; i < str1。length(); i++) {

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 charCountMap = new HashMap<>();        for (int i = 0; i < str。length(); i++) {

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 set = permutationOfString(“ABC”);

System。out。println(“Permutations of String ABC are:”);        for (String str : set) {

System。out。println(str);

}

}    public static Set permutationOfString(String str) {

Set permutationSet = new HashSet<>();        if (str。length() == 1) {

permutationSet。add(str);            return permutationSet;

}

char c = str。charAt(0);        String rem = str。substring(1);

Set permutatedSetForRemainingString = permutationOfString(rem);        for (String permutedString : permutatedSetForRemainingString) {            for (int j = 0; j <= permutedString。length(); j++) {                String permutation = insertFirstCharAtDiffPlaces(permutedString, c, j);

permutationSet。add(permutation);

}

}        return permutationSet;

}    public static String insertFirstCharAtDiffPlaces(String perm, char firstChar, int index) {        return perm。substring(0, index) + firstChar + perm。substring(index);

}

}

小結

以上就是本期的所有內容,怎麼樣,這些方法你都想到了嗎?如果你有更好的方法歡迎留言交流。

如果對你有幫助,點個贊是對我最大的鼓勵。