简体   繁体   中英

Alternative to nesting for-loops to improve performance of the code?

I have made a small program which checks which index needs to be deleted to make it a Palindrome. As there can be many test cases in a single execution, I'm forced to use deep nesting of for loops. I want to know if there is any alternative way to nesting loops for performance improvement.

Following is my code:

 import java.util.*;
 import java.io.*;
 public class Testhis {
 public static void main(String[] args) throws Exception {
      Scanner sc=new Scanner(System.in);
     //System.out.println("No. of testcases:");
     int testcases=sc.nextInt();
     String strin[]=new String[testcases];

     for (int i=0;i<testcases;i++)
            strin[i]=sc.next();
     int res[]= checkPalindromeIndex(strin);
     for(int i=0;i<res.length;i++)
       System.out.println(res[i]);
     }

   private static int[] checkPalindromeIndex(String[] strin) {
      int result[]=new int[strin.length];
      a:
      for(int i=0;i<strin.length;i++){
        System.out.println("checking:::::"+strin[i]);
        if(checkPalFlag(strin[i])){
            result[i]=-1;
            continue a;
        }
        else{

            for(int j=0;j<strin[i].length();j++){
                StringBuilder sb=new StringBuilder(strin[i]);
                String teststr=sb.deleteCharAt(j).toString();
                System.out.println("resulting string:"+teststr);
                if(checkPalFlag(teststr)){
                    result[i]=j;
                    continue a;
                }
            }

    }


 }
    return result;
}

private static boolean checkPalFlag(String string) {
    boolean flag=false;int len=string.length();
    for(int i=0;i<(len+1)/2;i++){
        if(string.charAt(i)==string.charAt(len-(i+1))){
            flag=true;
            continue;
        }
        else{
            flag=false;
            break;
        }
    }
    System.out.println("string "+string+" is a palindrome? :"+flag);
    return flag;
}

}

The following code will return all palindromes of a text.

private static String[] findAllPalindromesInText(String text) {
    // Eliminate all non-letter/digit from text
    String normalized = text.toLowerCase(Locale.ROOT).replaceAll("[^\\p{Ll}\\p{N}]", "");
    // Collect all palindromes
    Set<String> allPalindromes = new HashSet<>();
    findPalindromes(normalized, 0, normalized.length() - 1, "", "", allPalindromes);
    // Sort palindromes
    String[] result = allPalindromes.toArray(new String[allPalindromes.size()]);
    Arrays.sort(result, (s1, s2) -> {
        int cmp = Integer.compare(s2.length(), s1.length()); // sort longest first
        if (cmp == 0)
            cmp = s1.compareTo(s2); // sort by text
        return cmp;
    });
    return result;
}
private static void findPalindromes(String text, int first, int last,
                                    String prefix, String suffix, Set<String> allPalindromes) {
    for (int i = first; i <= last; i++) {
        char ch = text.charAt(i);
        allPalindromes.add(prefix + ch + suffix);
        for (int j = last; j > i; j--)
            if (text.charAt(j) == ch) {
                allPalindromes.add(prefix + ch + ch + suffix);
                findPalindromes(text, i + 1, j - 1, prefix + ch, ch + suffix, allPalindromes);
            }
    }
}

Test result

// for input "abcb"
[bcb, bb, a, b, c]

// for input "alibaba"
[ababa, abba, aaa, aba, aia, ala, bab, aa, bb, a, b, i, l]

// for input "abcdabdcabc"
[acdadca, acdbdca, bcdadcb, bcdbdcb, acddca, bcddcb, ababa, abcba, abdba, acaca, acbca, acdca, adada, adbda, babab, bacab, badab, bcacb, bcbcb, bcdcb, bdadb, bdbdb, cabac, cacac, cadac, cbabc, cbcbc, cbdbc, cdadc, cdbdc, abba, acca, adda, baab, bccb, bddb, caac, cbbc, cddc, aaa, aba, aca, ada, bab, bbb, bcb, bdb, cac, cbc, ccc, cdc, dad, dbd, aa, bb, cc, dd, a, b, c, d]

The last 3 parameters of findPalindromes() are used to collect the results. If you want to collect the indexes of the palindrome characters, you can change to do that.

If you want the indexes of characters to remove, I'd suggest you collect the indexes of the palindrome characters, ie indexes-to-keep, and then invert the results to indexes-to-remove after findPalindromes() returns.

Please note that although this algorithm is simpler than yours, it may not be faster, if you want longest palindrome, because you have to search all potential palindromes. Notice how the 3rd test case does have a palindrome using the first 3 letters abcba , but the longest palindromes don't use all of the first 3 letters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM