减少两个String数组之间匹配时执行的比较次数

时间:2014-10-15 05:10:17

标签: java arrays string performance comparison

我正在使用下面的两个类比较三个String的数组。不使用任何哈希映射或更改我的代码结构太多(我无法更改findMatchingElements()的签名),有没有办法最小化我的方法所做的比较次数,以便构造新的共享元素数组?

在TestRun.java中,我在三个阵列上测试了我的代码,每个阵列有8个元素,这导致了46次比较。我希望实现较低的比较次数。有办法吗?

我尝试使用remove()方法从集合中删除一个字符串,一旦成功地与查询集合中的匹配元素进行比较。这阻止了一些冗余的比较,但并没有导致显着的减少。

import java.util.*;

public class CommonElements {

    int originalCollectionCount = 0;  
    Object[] originalCollections;    
    int listCount = 1;
    int matchCount;
    int comparisonCount = 0;                

    public Comparable[] findMatchingItems(Object[] collections)
    {   

        String[] queryArray = (String[])collections[0]; 
        String[] secondaryArray = (String[])collections[1];

        ArrayList<String> queryList = new ArrayList(Arrays.asList(queryArray));
        ArrayList<String> secondaryList = new ArrayList(Arrays.asList(secondaryArray));
        ArrayList<String> commonList = new ArrayList();       

        int  i = 0;

        if(listCount == 1){  
            originalCollectionCount = collections.length;
            originalCollections = collections;
        }

        listCount ++;                               

        for(String x:queryList)
        {            
            for(String y:secondaryList)
            {                      
                comparisonCount++;                 
                if(x.compareTo(y) == 0)
                { 
                    commonList.add(x); //add mutually shared item to commonList
                    secondaryList.remove(y); //remove mutually shared item from consideration
                    if(originalCollectionCount == listCount) //if every list has been examined
                    {
                        System.out.println(commonList.get(i));                                                    
                    }
                    i++;  
                    break;
                }
            }
        }

        String[] commonListResult = new String[commonList.size()];
        commonList.toArray(commonListResult);           

        if(originalCollectionCount > listCount){ 
            findMatchingItems(new Object[] {commonListResult,originalCollections[listCount]});}

        if (collections.length == 0) {
            return new Comparable[0];
        } else if (collections.length == 1) {
            return (Comparable[]) collections[0];
        }                
        return commonListResult;
    }

    public int getComparisons(){
        return comparisonCount;}        
}


    public class TestRun {

private final static String[] COLLECTION_5_1 = {"Pittsburgh", "New York", "Chicago", "Cleveland", "Miami", "Dallas", "Atlanta", "Detroit"};
private final static String[] COLLECTION_5_2 = {"Dallas", "Atlanta", "Cleveland", "Chicago", "Washington", "Houston", "Baltimore", "Denver"};
private final static String[] COLLECTION_5_3 = {"Chicago", "Kansas City", "Cleveland", "Jacksonville", "Atlanta", "Tampa Bay", "Dallas", "Seattle"}; 

    public static void main(String[] args) {
        new TestRun();       
    }

    public TestRun() {

        CommonElements commonElements = new CommonElements();                

        Object[] input = new Object[3];
        input[0] = COLLECTION_5_1;
        input[1] = COLLECTION_5_2;
        input[2] = COLLECTION_5_3;    

        System.out.println("Matching items:");
        commonElements.findMatchingItems(input);

        System.out.println(commonElements.comparisonCount + " comparisons made.");  



    }
}

3 个答案:

答案 0 :(得分:0)

您可以运行单个高级for循环,如下所示,如果不相应地运行,则两个数组的长度相同。

for(String str:arrayStr1){
if(arrayStr2.contains(str)){
newArray.add(str);
}
}

答案 1 :(得分:0)

List<String> list_5_1 = new ArrayList<>(Arrays.asList(COLLECTION_5_1));
//[Pittsburgh, New York, Chicago, Cleveland, Miami, Dallas, Atlanta, Detroit]
List<String> list_5_2 = new ArrayList<>(Arrays.asList(COLLECTION_5_2));
//[Dallas, Atlanta, Cleveland, Chicago, Washington, Houston, Baltimore, Denver]

list_5_1.retainAll(list_5_2);
//[Chicago, Cleveland, Dallas, Atlanta]

We have to pass list returned from Arrays.asList, as Arrays.asList method returns only immutable list.

答案 2 :(得分:0)

  

使用下面的两个类比较三个字符串数组。不使用任何哈希映射或更改我的代码结构太多(我无法更改find​​MatchingElements()的签名),有没有办法最小化我的方法所做的比较次数,以便构造新的数组共享元素?

不确定。您的嵌套循环具有O(m*n)的复杂性。当您创建临时HashMap时,可以将其缩减为O(m+n),并为大输入获得大量收益。从实际的POV来看,大约10的长度应该比你的解决方案更快。

我没有提供任何代码,因为它过于简单。