2015-10-15 130 views
0

我剛剛完成了下面代碼中註釋塊中描述的小任務,但我一直試圖通過將getRareDigitsdisplayRareDigits合併爲一個函數來使代碼更好。無論我做什麼,邏輯總是最終打破。任何人都可以向我解釋這兩種功能是否可以合併?謝謝^ _^這兩個功能可以合併爲一個嗎?

/* 
    Written by: Stephanie Yumiko 

* This program will ask the user 
for a series of integers, defined by 
the user. 

* The program will display back to the 
user the number of rare digits, digits 
that only occur once in a single integer, 
but not the rest. 

* The program will then sort the integers 
based on the number of occurrences of 
rare digits it contains, from greatest 
to least. 
*/ 

#include <iostream> 
using namespace std; 

bool num_contains(int, int); 
void showRareDigits(int*, int); 
void sortRareDigits(int*, int* , int); 

bool num_contains(int digit, int n) { 
    while (n) { 
     if (digit == n % 10) return true; 
     n /= 10; 
    } 
    return false; 
} 

void getRareDigits(int *arr, int *ordered, int len) { 
    for (int index = 0; index < len; ++index) { 
     int n = arr[index]; 
     if (n < 0) 
      n *= -1; 
     int d = 0; 
     while (n) { 
      d = n % 10; 
      int i;  // keep track of loop counter outside the loop 
      int stop = 0; // to break out loop 
      for (i = 0; i < len; ++i) { 
       if (i != index && num_contains(d, arr[i])) 
        stop = 1; 
      } 
      // only increment the array if the loop exited before 
      // completing (implying the goto would have happened) 
      if (!stop) { 
       ++ordered[index]; 
      } 
      // always execute 
      n /= 10; 
     } 
    } 

    for (int i = 0; i<len; i++) { 
     for (int j = 0; j<len - i - 1; j++) { 
      if (ordered[j]<ordered[j + 1]) { 
       int temp = ordered[j]; 
       ordered[j] = ordered[j + 1]; 
       ordered[j + 1] = temp; 

       int temp2 = arr[j]; 
       arr[j] = arr[j + 1]; 
       arr[j + 1] = temp2; 
      } 
     } 
    } 

    cout << "\nArray after sort:\n"; 
    for (int i = 0; i < len; i++) { 
     cout << arr[i] << endl; 
    } 
} 

void showRareDigits(int* iAry, int size) { 
    const int size2 = 10; 
    int* tmpAry = new int[size]; 
    int totalCount[size2] = { 0 }; 
    int currentCount[size2] = { 0 }; 
    int totalUncommon = 0; 
    int i, j; 
    int* ordered; 
    ordered = new int[size]; 

    for (i = 0; i < size; i++) { 
     ordered[i] = 0; 
     tmpAry[i] = iAry[i]; 
     if (tmpAry[i] < 0) 
      tmpAry[i] *= -1; 

     for (j = 0; j < size2; j++) 
      currentCount[j] = 0; 

     if (tmpAry[i] == 0) { 
      currentCount[0] = 1; 
     } 

     while (tmpAry[i]/10 != 0 || tmpAry[i] % 10 != 0){ 
      currentCount[tmpAry[i] % 10] = 1; 
      tmpAry[i] /= 10; 
     } 

     for (j = 0; j < size2; j++) { 
      totalCount[j] += currentCount[j]; 
     } 
    } 

    for (i = 0; i < size2; i++) { 
     if (totalCount[i] == 1) { 
      totalUncommon++; 
     } 
    } 

    cout << "\nTotal rare digits: " << totalUncommon << endl 
     << "\nThe rare digits:\n"; 
    if (totalUncommon == 0) { 
     cout << "\nNo rare digits found."; 
    } 
    else { 
     for (i = 0; i < size2; i++) { 
      if (totalCount[i] == 1) { 
       cout << i << endl; 
      } 
     } 
    } 

    getRareDigits(iAry, ordered, size); 

    delete[] tmpAry; 
    delete[] ordered; 

    return; 
} 


int main() {  
    int size; 
    int* arr; 

    cout << "Enter # of integers: "; 
    cin >> size; 
    arr = new int[size]; 

    for (int i = 0; i < size; i++) { 
     cout << "Enter the value for #" << i << " : "; 
     cin >> arr[i]; 
    } 

    cout << "Array before sorting:\n"; 
    for (int i = 0; i < size; i++) { 
     cout << arr[i] << endl; 
    } 

    showRareDigits(arr, size); 

    delete[] arr; 

    return 0; 
} 
+5

*誰能給我解釋一下,如果有可能這兩個功能甚至可以結合在一起嗎?*結合兩個功能並不難。我的建議將不會嘗試。擁有比一個大功能更小且明確定義的功能會更好。 –

+0

我建議編寫一些小功能,它們可以做不止一次的東西。所以,如果一個函數是基於某些輸入來計算某些東西的,它應該將計算結果返回給調用者,而不是將它們打印到屏幕上並不返回任何內容。用這樣的小函數構建代碼,並將它們組合到一個「應用程序」中。 – juanchopanza

+0

實際的改進是使用'std :: vector'並將任務* more *分開,而不是更少。除非你能描述每個單個函數所做的是一個句子,而不用「and」或「or」這個詞,否則它可能太複雜了。 – molbdnilo

回答

1

你的兩個功能是大而笨重的。有時難以避免,但將它們合併爲一個並不是一個好主意。

而是嘗試弄清楚哪些邏輯對他們來說很常見,並將其放入可用於get ...和display ...函數中的單個函數中。

你也應該看看繼續打破突圍循環。儘管流行的觀點轉到是一個可行的選擇打破多個循環水平,可用於簡化您的代碼,使其更短,更容易理解。

+0

我的教授說不要使用break,continue或者goto,除非你在'switch'語句中,不知道爲什麼,但是我遵循了他的指示。謝謝,我會牢記這一點。 :) –

+0

他可能只是希望你專注於語言的某些方面。他告訴你不要做某件事並不一定意味着它是錯的。這不是你應該練習的。 – kamikaze

1

這兩個函數之間有一些共同點和一些很大的差異。這意味着做一件事情做這兩件事絕對不是正確的做法。

打破常規功能,並保留功能的整體邏輯。例如,編寫一個識別整數中罕見數字的函數將有助於您的代碼,因爲您需要在兩個不同位置的信息,並且您有循環來計算這兩個地方。

0

這不是一個真正的答案,因爲你不應該結合這些功能。
相反,你應該以不同的方式考慮程序。

這是我的建議:

,你打破了數分解成獨立的數字3米的地方,所以這顯然是一個單獨的功能的工作。
用字符串做這件事更容易,因爲我們對數字不感興趣,只是它們是否是唯一的。

// Return the number of "rare" digits in 'i'; digits which occur only once. 
int rare_digits(int i) 
{ 
    std::map<char, int> frequency; 
    std::string s = std::to_string(i); 
    // Count the characters 
    for (auto c : s) 
    { 
     frequency[c]++; 
    } 
    // Count how many were unique 
    int rare = 0; 
    for (auto f: frequency) 
    { 
     if (f.second == 1) 
     { 
      rare++; 
     } 
    } 
    return rare; 
} 

如果我們將數據存儲在一個結構中,我們可以攜帶罕見數字以及數字本身。
這樣,我們只需要計算一次數字。

struct Rarity 
{ 
    Rarity(int n, int r) 
     : number(n), 
      rarity(r) {} 
    int number; 
    int rarity; 
}; 

的分類,自定義比較操作符是有用的:

bool operator< (const Rarity& lhs, const Rarity& rhs) 
{ 
    return lhs.rarity > rhs.rarity; 
} 

其他一切我們需要的是標準庫提供:

int main() 
{ 
    std::vector<Rarity> numbers; 
    int input = 0; 
    while (std::cin >> input) 
    { 
     int rarity = rare_digits(input); 
     // Filter out the "non-rare" numbers early, since they're not interesting 
     if (rarity > 0) 
     { 
      numbers.emplace_back(input, rarity); 
     } 
    } 

    std::sort(numbers.begin(), numbers.end()); 
    std::cout << numbers.size() << " numbers contained rare digits." << std::endl; 
    std::cout << "These numbers were:" << std::endl; 
    for (const auto& r: numbers) 
    { 
     std::cout << r.number << " (" << r.rarity << " rare digits)" << std::endl; 
    } 
} 
相關問題