【问题标题】:Reducing the number of comparisons performed when matching between two String arrays减少在两个字符串数组之间匹配时执行的比较次数
【发布时间】:2014-10-15 05:10:17
【问题描述】:

我正在使用下面的两个类比较三个 Strings 数组。在不使用任何哈希映射或过多更改代码结构的情况下(我无法更改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.");  



    }
}

【问题讨论】:

    标签: java arrays string performance comparison


    【解决方案1】:

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

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

    【讨论】:

    • 这不会减少比较次数。
    【解决方案2】:
    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.
    

    【讨论】:

    • 这很好,但不会减少比较次数。
    【解决方案3】:

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

    当然。您的嵌套循环的复杂度为O(m*n)。当您创建一个临时的HashMap 时,您可以将其减少到O(m+n) 并获得大量输入。从实际的 POV 来看,大约 10 的长度应该比您的解决方案更快。

    我没有给出代码,因为它太简单了。

    【讨论】:

      猜你喜欢
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多