【问题标题】:Alternative to nesting for-loops to improve performance of the code?替代嵌套 for 循环以提高代码性能?
【发布时间】:2015-11-06 07:09:03
【问题描述】:

我做了一个小程序,它检查需要删除哪个索引以使其成为回文。由于一次执行中可能有很多测试用例,我不得不使用 for 循环的深层嵌套。我想知道是否有任何替代方法可以嵌套循环以提高性能。

以下是我的代码:

 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;
}

}

【问题讨论】:

  • 我投票结束这个问题,因为这个问题属于Code Review。
  • 你的意思是这不是一个有效的问题吗?我不希望我的代码被审查..我想要问题的解决方案不是要审查的代码。代码只是一个例子
  • 也许用书面文字/伪代码而不是实际代码来解释你的方法会更好
  • 对于输入abcb,我可以看到以下palindromes:a,b,c,bb,bcb。你想要哪一个?如果是第一个,答案是删除索引 1、2、3。如果是最后一个,答案是删除索引 0。你没有说你想要最长的回文,所以第一个是最简单的,但是如果你确实想要最长的,如果有多个候选最长回文,你想要哪一个?
  • 您是否在寻找最短回文、最长回文、任何或每种可能的组合?

标签: java performance loops for-loop nested


【解决方案1】:

以下代码将返回文本的所有回文。

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);
            }
    }
}

测试结果

// 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]

findPalindromes()的最后3个参数用于收集结果。如果你想收集回文字符的索引,你可以改变这样做。

如果你想删除字符的索引,我建议你收集回文字符的索引,即indexes-to-keep,然后在findPalindromes()返回后将结果反转为indexes-to-remove。

请注意,虽然这个算法比你的更简单,但如果你想要最长的回文,它可能不会更快,因为你必须搜索所有潜在的回文。请注意,第 3 个测试用例确实有一个使用前 3 个字母 abcba 的回文,但最长的回文并不使用前 3 个字母。

【讨论】:

  • +1。您还可以使用标准比较器进行排序:Arrays.sort(result, Comparator.comparingInt(String::length).reversed().thenComparing(Comparator.natural‌​Order()));
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 2020-12-22
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
相关资源
最近更新 更多