2015-10-15 2 views
0

Я только что закончил работу над мини-задачей, описанной в блоке комментариев в приведенном ниже коде, но я пытался сделать код лучше, объединив getRareDigits и displayRareDigits в одну функцию. Независимо от того, что я делаю, логика всегда заканчивается. Может ли кто-нибудь объяснить мне, возможно ли, чтобы эти две функции были объединены? Спасибо^_^Можно ли объединить эти две функции в одну?

/* 
    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' и отделить задачи * больше *, не менее. Если вы не можете описать, что делает каждая отдельная функция, это одно предложение без использования слов «и» или «или», это, вероятно, слишком сложно. – molbdnilo

ответ

1

Ваши две функции большие и неуклюжие, как есть. Иногда этого трудно избежать, но объединение их в одно - не очень хорошая идея.

Вместо этого попытайтесь выяснить, какая из них является общей для них и поместить это в отдельные функции, которые вы можете использовать из функций get ... и display ....

Кроме того, вы должны взглянуть на продолжить и перерыв вырваться из петли. Несмотря на распространенное мнение goto - это жизнеспособный вариант выхода из нескольких уровней цикла и может быть использован для упрощения вашего кода и упрощения его понимания.

+0

Мой профессор сказал, что не используйте break, continue или goto, если вы не находитесь в заявлении 'switch', не знаете почему, но я следовал его инструкциям. Спасибо, я буду помнить об этом. :) –

+0

Он может просто захотеть, чтобы вы сосредоточились на определенных аспектах языка. То, что он сказал вам не делать что-то, не обязательно означает, что это неправильно. Это просто не то, что вы должны практиковать. – kamikaze

1

Существует некоторая общность и некоторые большие различия между этими двумя функциями. Это означает, что сделать одну функцию для выполнения обеих задач - это, безусловно, не совсем то, что нужно делать.

Нарушение функциональности COMMON и оставление общей логики в функциях как есть. Например, запись функции, которая идентифицирует редкие цифры в целых числах, поможет вашему коду, потому что вам нужна эта информация в двух разных местах, и у вас есть петли для вычисления этого в обоих местах.

0

На самом деле это не ответ, потому что вы не должны комбинировать эти функции.
Вместо этого вы должны разделить программу по-разному.

Это мое предложение:

Есть три места, где ломают число на отдельные цифры, так что это явно работа отдельной функции.
Это проще сделать со строками, поскольку нас не интересуют цифры :, только они уникальны.

// 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; 
    } 
} 
Смежные вопросы