簡體   English   中英

用多個if-else語句(多個條件)優化函數的最佳方法是什么?

[英]What is the best way to optimize a function with many if-else statements(multiple conditions)?

什么是優化下面代碼的最佳方法或設計模式是什么?(我曾考慮過使用switch語句,但是switch語句無法在單個情況下處理多個條件。)

下面是代碼片段。 每個專業都由某個數值范圍確定。

public String getMajor(String major) {
    crnCompare = Integer.parseInt(major);
    if ((crnCompare >= 90702 && crnCompare <= 90733) || (crnCompare >= 10004 && crnCompare <= 10037)) {
        this.major = "AC";
    } else if ((crnCompare >= 10087 && crnCompare <= 10108) || (crnCompare >= 10471 && crnCompare <= 10482) || (crnCompare >= 90024 && crnCompare <= 90071)) {
        this.major = "CS";
    } else if ((crnCompare >= 10109 && crnCompare <= 10158) || (crnCompare >= 90072 && crnCompare <= 90116)) {
        this.major = "EC";
    } else if ((crnCompare >= 90117 && crnCompare <= 90203) || (crnCompare >= 10075 && crnCompare <= 10213) || (crnCompare >= 10498 && crnCompare <= 10572)) {
        this.major = "EN";
    } else if ((crnCompare >= 10038 && crnCompare <= 10040) || (crnCompare >= 10214 && crnCompare <= 10255) || (crnCompare >= 10256 && crnCompare <= 10260) || (crnCompare >= 90017 && crnCompare <= 90203) || crnCompare == 11172) {
        this.major = "FI";
    } else if ((crnCompare >= 90670 && crnCompare <= 90790) || (crnCompare >= 11236 && crnCompare <= 11239)) {
        this.major = "FS";
    } else if ((crnCompare >= 90253 && crnCompare <= 90273) || (crnCompare >= 90734 && crnCompare <= 90769) || (crnCompare >= 90274 && crnCompare <= 90360) || (crnCompare >= 10261 && crnCompare <= 10393)) {
        this.major = "GB";
    } else if ((crnCompare >= 100394 && crnCompare <= 10429) || (crnCompare >= 90361 && crnCompare <= 90398)) {
        this.major = "GLS";
    } else if ((crnCompare >= 10430 && crnCompare <= 10451) || (crnCompare >= 90399 && crnCompare <= 90420)) {
        this.major = "HI";
    } else if ((crnCompare >= 10452 && crnCompare <= 10468) || (crnCompare >= 90422 && crnCompare <= 90436) || crnCompare == 11119) {
        this.major = "IDCC";
    } else if ((crnCompare >= 9437 && crnCompare <= 90438) || (crnCompare >= 10469 && crnCompare <= 10470)) {
        this.major = "IPM";
    } else if ((crnCompare == 90421) || (crnCompare >= 11280 && crnCompare <= 11426)) {
        this.major = "ID";
    } else if ((crnCompare >= 90439 && crnCompare <= 90448) || (crnCompare >= 90483 && crnCompare <= 90497)) {
        this.major = "LTF";
    } else if ((crnCompare >= 90504 && crnCompare <= 90535) || (crnCompare >= 10573 && crnCompare <= 10596) || crnCompare == 90785) {
        this.major = "MG";
    } else if ((crnCompare >= 90536 && crnCompare <= 90553) || (crnCompare >= 10598 && crnCompare <= 10616) || crnCompare == 10740) {
        this.major = "MK";
    } else if ((crnCompare >= 90449 && crnCompare <= 90503) || (crnCompare >= 10514 && crnCompare <= 10564) || (crnCompare == 11120) || (crnCompare == 10555) || (crnCompare == 11127)) {
        this.major = "MA";
    } else if ((crnCompare >= 10637 && crnCompare <= 10715) || (crnCompare == 11142) || (crnCompare == 10739) || (crnCompare >= 90575 && crnCompare <= 90622)) {
        this.major = "NAS";
    } else if (crnCompare >= 90554 && crnCompare <= 90574 || crnCompare == 10617 || crnCompare == 10636) {
        this.major = "ML";
    } else if ((crnCompare >= 90623 && crnCompare <= 10646) || (crnCompare >= 10671 && crnCompare <= 10696)) {
        this.major = "PI";
    } else if ((crnCompare == 90647 || crnCompare == 90649) || (crnCompare >= 10697 && crnCompare <= 10698) || crnCompare == 10756) {
        this.major = "PRS";
    } else if ((crnCompare >= 11341 && crnCompare <= 11420)) {
        this.major = "SL";
    } else if ((crnCompare >= 90650 && crnCompare <= 90668) || (crnCompare >= 10716 && crnCompare <= 10734)) {
        this.major = "SO";
    } else if ((crnCompare == 10735)) {
        this.major = "ST";
    }

    return this.major;
}

您可能想研究Guava的RangeMap類(其他類似的實現方式也可用)。

這些使您可以表達這些條件,如下所示:

RangeMap<Integer, String> rangeMap =
  ImmutableRangeMap.<Integer, String>builder()
    .put(Range.closed(90702, 90733), "AC")
    .put(Range.closed(10004, 10037), "AC")
    .put(Range.closed(10087, 10108), "EN")
    .put(Range.closed(10004, 10037), "AC")
    // ...
    .build();

構造一次,然后查詢如下:

String major = rangeMap.get(crmCompare);

有兩個優點:

  • 這是一種更緊湊的語法
  • 驗證了范圍的創建,最小和最大均處於正確的順序,並且沒有重疊。

缺點是添加了番石榴,如果您還沒有使用過的話。

標准表驅動方法:

public static class Range
{
    // getters omitted for conciseness
    int low;
    int high;
    String major;
    public Range(int low, int high, String major)
    {
        this.low  = low;
        this.high  = high;
        this.major = major;
    }
    public boolean contains(int v)
    {
        return (v >= low && v <= high);
    }
}

public static Range[] ranges = {
        new Range(10004,10037,"AC"),
        new Range(10087,10108,"AC"),
        // etc
        // Ideally this table is populated from a data file that can
        // be updated at runtime without recompiling the code.
};

public String getMajor(String m)
{
    int crnCompare = Integer.parseInt(m);
    // Search for the matching range
    for (Range r : ranges)
        if (r.contains(crnCompare)) return r.major;
    return null;
}

將所有條件編碼為低-高對和相應的主代碼,然后將所有條件放入數組中。 要確定主要搜索數組,以找到匹配條件。

可能的增強(保留為練習)包括

  1. 從文件加載表,而不是對其進行硬編碼
  2. 保持表格排序,以便您可以執行二進制搜索而不是線性搜索。

我想了一會兒。 關注以下方面:“如何確保實現正確?”

從這個意義上講,我會建議一個Range類,類似於Jim提出的類。 因為這樣的類使您不僅可以擁有一個與范圍數據緊密相關的contains()方法,而且還可以使您擁有一個與范圍數據緊密相關的contains()方法。 但最重要的是,您可以添加以下方法:

  • boolean isOverlapping(Range other) ...可以用來檢測不注意的情況,並且您定義的范圍可以重疊!
  • int compareTo(Range other) ...實現Comparable接口。 現在您可以范圍進行排序 當某個“類別”的范圍列表太大時,這將允許您執行二進制搜索。

但是:我不會將“主要”名稱放到Range類中。 但是反過來:

public enum RangeBasedMajor {
  AC(Arrays.asList(new Range(90702, 90733), new Range(...)),
  EN(...

  private RangeBasedMajor(List<Range> ranges) ...

這里的重點:

  • 您在一個地方創建了這些“專業”並將其映射到其范圍
  • 您可以編寫一些不錯的單元測試,以從該枚舉中獲取所有常量,然后grep其范圍,以確保沒有范圍重疊
  • 而且您仍然可以將所有信息隨意放入Andy在其解決方案中推薦給您的特殊地圖類型中...

根據您的情況,這可能會過分殺傷力。 這實際上取決於您期望事物在其中發生變化的頻率。 例如:如果需要訪問/處理程序其他部分中的“主要”信息。 當您只需要將該數字映射到字符串時(例如用於打印內容); 那么RangeMap就可以了。

但是,當您有其他代碼與“專業”打交道時,那么值得在這里提出一些建議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM