我有一个问题说明,需要实现一些数据结构,进而实现两个功能

时间:2019-06-10 15:17:24

标签: java data-structures

证券被映射到资产类别。在一段时间内,安全性可以转移到另一个类别。下表是例如

的表格
Security   Asset_category     Start_date   End_date
-----------------------------------------------------
aalp       US_LARGE_CAP       1/1/2015     2/17/2015
aalp       US_LARGE_GROWTH    2/18/2015    3/16/2015

我必须实现两个功能

fetchAssetCategory(String security , Date inputDate) 

这将返回当时用于安全性的资产类别名称

validateSecurity(String security , String assetCat , Date inputDate)

将在该时间点验证安全性。

样本输入

fetchAssetCategory("aalp", "1/20/2015") : return : US_LARGE_CAP
validateSecurity("aalp", "US_LARGE_GROWTH", 2/17/2015) : return false

必须使用数据结构并提及时间和空间的复杂性

我尝试过使用Hashmap,但陷入了中间

任何帮助将不胜感激。

public String fetchAssetCategory(String security, Date inputDate) throws ParseException {
    // Approach-1
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
    sdf.setLenient(false);
    /*
     * String date = sdf.format(inputDate); System.out.println(date);
     */

    ArrayList<Date> startDates = new ArrayList<>();
    startDates.add(sdf.parse("01/01/2015"));
    startDates.add(sdf.parse("02/18/2015"));
    startDates.add(sdf.parse("08/18/2015"));
    startDates.add(sdf.parse("03/17/2015"));
    startDates.add(sdf.parse("05/18/2015"));

    ArrayList<Date> endDates = new ArrayList<>();
    endDates.add(sdf.parse("02/17/2015"));
    endDates.add(sdf.parse("03/16/2015"));
    endDates.add(sdf.parse("12/15/2015"));
    endDates.add(sdf.parse("05/17/2015"));
    endDates.add(sdf.parse("08/17/2015"));

    ArrayList<Security> addRecords = new ArrayList<>();
    Security s1 = new Security("AAPL", "US LARGE CAP VALUE", startDates.get(0), endDates.get(0));
    Security s2 = new Security("AAPL", "US LARGE CAP GROWTH", startDates.get(1), endDates.get(1));
    Security s3 = new Security("AAPL", "US MID CAP VALUE", startDates.get(2), endDates.get(2));
    Security s4 = new Security("AAPL", "US LARGE CAP VALUE", startDates.get(3), endDates.get(3));
    Security s5 = new Security("AAPL", "US MID CAP GROWTH", startDates.get(4), endDates.get(4));
    addRecords.add(s1);
    addRecords.add(s2);
    addRecords.add(s3);
    addRecords.add(s4);
    addRecords.add(s5);

    for (int i = 0; i < addRecords.size(); i++) {
        if (security.equalsIgnoreCase(addRecords.get(i).getSecurity())
                && (inputDate.before(addRecords.get(i).getEndDate())
                        && inputDate.after(addRecords.get(i).getStartDate()))) {
            return (addRecords.get(i).getAssetCategory());
        }
    }

    return "";
}

public static void main(String args[]) {
    SecurityAssest sa = new SecurityAssest();
    try {
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        java.util.Date yourDate = sdf.parse("01/20/2015");
        sa.fetchAssetCategory("AAPL", yourDate);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

1 个答案:

答案 0 :(得分:0)

您可以通过对类别列表进行排序来改善这一点,以便我们可以执行二进制搜索来查找日期。这里的假设是,同一证券的类别没有重叠的日期。

为此,我们将创建一个比较器,该匹配器将匹配具有交叉点的所有资产类别。

public class IntersectComparator implements Comparator<AssetCategory> {
    public int compare(AssetCategory l, AssetCategory r) {
        if (l.getEnd().isBefore(r.getStart())) {
            return -1;
        }
        if (r.getEnd().isBefore(l.getStart())) {
            return 1;
        }
        return 0;
    }
}

这使我们既可以计算插入位置,又可以执行二进制搜索。

public class AssetCategories {
    private final static Comparator<AssetCategory> COMPARATOR = new IntersectComparator();

    private Map<String, List<AssetCategory>> assets = new HashMap<>();

    public void add(AssetCategory assetCategory) {
        List<AssetCategory> categories = assets.computeIfAbsent(assetCategory.getAsset(), k -> new ArrayList<>());
        int insert = Collections.binarySearch(categories, assetCategory, COMPARATOR);
        if (insert >= 0) {
            throw new IllegalArgumentException("Asset category dates intersect with existing asset category");
        }
        categories.add(-insert - 1, assetCategory);
    }

    public AssetCategory fetchAssetCategory(String asset, LocalDate date) {
        List<AssetCategory> categories = assets.get(asset);
        if (categories == null) {
            return null;
        }
        int index = Collections.binarySearch(categories,
                new AssetCategory(asset, "SEARCH", date, date),
                COMPARATOR);

        return index < 0 ? null : categories.get(index);
    }

    public boolean validateAssetCategory(String asset, String category, LocalDate date) {
        AssetCategory assetCategory = fetchAssetCategory(asset, date);
        return assetCategory != null && assetCategory.getCategory().equalsIgnoreCase(category);
    }
}

您将按以下方式使用它:

        AssetCategories categories = new AssetCategories();
        categories.add(new AssetCategory("AAPL", "US LARGE CAP VALUE", LocalDate.parse("2015-01-01"), LocalDate.parse("2015-02-17")));
        categories.add(new AssetCategory("AAPL", "US LARGE CAP GROWTH", LocalDate.parse("2015-02-18"), LocalDate.parse("2015-03-16")));
        categories.add(new AssetCategory("AAPL", "US MID CAP VALUE", LocalDate.parse("2015-08-18"), LocalDate.parse("2015-12-15")));
        categories.add(new AssetCategory("AAPL", "US LARGE CAP VALUE", LocalDate.parse("2015-03-17"), LocalDate.parse("2015-05-17")));
        categories.add(new AssetCategory("AAPL", "US MID CAP GROWTH", LocalDate.parse("2015-05-18"), LocalDate.parse("2015-08-17")));

        AssetCategory assetCategory = categories.fetchAssetCategory("AAPL", LocalDate.parse("2015-12-14"));
        boolean valid = categories.validateAssetCategory("AAPL", "US MID CAP VALUE", LocalDate.parse("2015-12-15"));

这看起来像是课程,因此您的讲师可能正在寻找您使用树状图作为数据结构。