这两个功能能合二为一吗?
Can these two functions be combined into one?
我刚刚完成了下面代码中注释块中描述的一个迷你任务,但是我一直试图通过将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;
}
这两个函数既大又笨重。有时候这是很难避免的,但是把它们合二为一并不是一个好主意。
相反,尝试找出它们的共同逻辑,并将其放入您可以从get…和display…函数中使用的单个函数中。
你还应该看看continue和break来跳出循环。尽管人们普遍认为goto是跳出多个循环级别的可行选择,并且可以用来简化代码,使其更短,更容易理解。
这两个函数有一些共同之处,也有一些很大的不同。这意味着让一个函数同时做这两件事肯定是不对的。
拆分COMMON功能,并保留函数中的整体逻辑。例如,编写一个识别整数中的稀有数字的函数将有助于您的代码,因为您在两个不同的地方需要该信息,并且您有循环在两个地方计算该信息。
这不是一个真正的答案,因为您不应该将这些函数组合在一起。
相反,您应该对程序进行不同的分解。
这是我的建议:
有三个的地方,你把一个数字分解成单独的数字,所以这显然是一个单独的函数。
使用字符串更容易做到这一点,因为我们不关心数字是什么,只关心它们是否唯一。
// 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;
}
}
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 对可变参数使用声明.如何选择正确的功能
- 如何将3个功能合二为一?
- 如何将多个功能合二为一
- 这两个功能能合二为一吗?