我刚刚完成了下面代码中注释块中描述的迷你任务,但我一直试图通过将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;
}
答案 0 :(得分:1)
你的两个功能很大很笨重。有时难以避免,但将它们合并为一个并不是一个好主意。
而是试图弄清楚哪些逻辑对他们来说是常见的,并将其放入可以从get ...和display ...函数中使用的各个函数中。
此外,您应该看一下 continue 和 break 以打破循环。尽管普遍认为 goto 是打破多个循环级别的可行选项,可用于简化代码并使其更简单易懂。
答案 1 :(得分:1)
这两个功能之间存在一些共性和一些重大差异。这意味着制作一个功能来做这两件事绝对不是正确的事情。
打破COMMON功能,并将整个逻辑保留在函数中。例如,编写一个标识整数中稀有数字的函数将有助于您的代码,因为您需要在两个不同的位置使用该信息,并且您有两个循环来计算这两个位置。
答案 2 :(得分: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;
}
}