我有下面这个名为solution
的java方法,有两个大的for循环,正如你所看到的,两个for循环是非常samilar,所以我认为有可能通过像这样的方法来重构代码public int getElementSize(ArrayList<Integer> factor1, ArrayList<Integer> factor2)
执行for循环的工作,所以我可以用不同的参数调用该方法两次,而不是重复两个for循环。但是因为这两个for循环有不同的循环次序,一个是从头到尾,另一个是从尾到头,除此之外,循环的所有其他部分是相同的,任何想法如何重构这段代码?
class Solution {
public int solution(int[] A) {
ArrayList<Integer> factor1 = new ArrayList<Integer>();
ArrayList<Integer> factor2 = new ArrayList<Integer>();
int factor = 1;
int N = A.length;
while(factor * factor <= N){
if(N % factor == 0){
factor1.add(factor);
factor2.add(N / factor);
}
factor++;
}
for(int i = 1; i < factor2.size(); i++){
int blockSize = factor2.get(i);
int elementSize = factor1.get(i);
int peaks = 0;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
if(peaks == blockSize)
return blockSize;
}
for(int i = factor1.size() - 1; i >= 0; i--){
int blockSize = factor1.get(i);
int elementSize = factor2.get(i);
int peaks = 0;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
if(peaks == blockSize)
return blockSize;
}
return 0;
}
}
答案 0 :(得分:1)
这个怎么样?
有条件的算子,?和:类似于,(这些被称为三元运算符,在编译时解析为if else块)
if(condition) {
this();
} else {
that();
}
在上面,你可以单行作为,(条件?this():that())
class Solution {
public int solution(int[] A) {
ArrayList<Integer> factor1 = new ArrayList<Integer>();
ArrayList<Integer> factor2 = new ArrayList<Integer>();
int factor = 1;
int N = A.length;
while(factor * factor <= N){
if(N % factor == 0){
factor1.add(factor);
factor2.add(N / factor);
}
factor++;
}
// let i = 0 to be factor2, i = 1 is factor 1
for(int i = 0; i < 2; i++) {
for(int x = (i == 0 ? 1 : factor1.size() - 1); (i == 0 ? x < factor2.size() : x >= 0); (i == 0 ? x++ : x--)){
int blockSize = (i == 0 ? factor2.get(x) : factor1.get(x));
int elementSize = (i == 0 ? factor1.get(x) : factor2.get(x));
int peaks = 0;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
if(peaks == blockSize)
return blockSize;
}
}
return 0;
}
}
答案 1 :(得分:0)
你可以将for循环中的代码重构为新方法,然后将两个大的for循环移动到新方法,这样,两个循环的顺序仍然是独立的,基本上它看起来如下,正确性需要验证,这只是一个不重复的想法:
class Solution {
public int solution(int[] A) {
ArrayList<Integer> factor1 = new ArrayList<Integer>();
ArrayList<Integer> factor2 = new ArrayList<Integer>();
int factor = 1;
int N = A.length;
while(factor * factor <= N){
if(N % factor == 0){
factor1.add(factor);
factor2.add(N / factor);
}
factor++;
}
for(int i = 1; i < factor2.size(); i++){
int blockSize = factor2.get(i);
int elementSize = factor1.get(i);
int peaks = getElementSize(A, blockSize, elementSize); //call the method
if(peaks == blockSize)
return blockSize;
}
for(int i = factor1.size() - 1; i >= 0; i--){
int blockSize = factor1.get(i);
int elementSize = factor2.get(i);
int peaks = getElementSize(A, blockSize, elementSize); //call the method
if(peaks == blockSize)
return blockSize;
}
return 0;
}
//this method include the code which was repeated inside the loops
public int getElementSize(int[] A, int blockSize, int elementSize){
int peaks = 0;
int N = A.length;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
return peaks;
}
}