计算特定数字并使用递归将偶数替换为0

时间:2018-11-16 19:02:21

标签: c++ recursion

我是C ++的新手,这是我的第一个艰巨任务,我在理解递归方面遇到困难。我需要编写一个递归函数,以计算用户输入5和8的次数。并将偶数替换为0。例如:

用户输入:4585

5&8的数量:3

甚至替换为0:0505

下面的代码是完全错误的,但这是我需要使用的语言。并注意它必须包含递归。我稍后可以调用该函数。

#include <iostream> 
using namespace std; 

int countThreeFives(int num) {
    static int count=0;

    int digit = num % 10; 
    if (n == 5 || n == 8)
    {
        count++;
        countThreeFives(num/10);
    }
    else
    {
        return count;
    }
}

int replaceEven(int num){ 
    int digit = num % 10;
    if (digit % 2 != 0) {
    // Confused here (incomplete)
    } 
int main() { 
    int x; 
    cout << "Enter a positive number: "; 
    cin >> x;

    cout << "The count of 8 & 5 is: " << countThreeFives(x); 
    cout << "Replacing even with 0: " << replaceEven(x);
}

5 个答案:

答案 0 :(得分:2)

我猜这是学校的作业,因此这里要求使用递归。无论如何,这是一个递归解决方案:

让我们用f(d,n)表示一串数字d的前n个数字中的5s和8s数。然后我们可以形成以下递归关系:

f(d,n)= 1 + f(d,n-1),如果第n位数字是5或8

如果第n个数字既不是5也不是8,则

f(d,n)= f(d,n-1)

我们的基本情况是f(d,0)= 0,因为大小为0的字符串将没有5s也没有8s

#include <iostream>
#include <string>

int countAndReplace(std::string& digits, int n)
{
    if(n == 0)
    {
        return 0;
    }
    bool addOne = (digits[n - 1] == '5' || digits[n - 1] == '8');
    if(digits[n - 1] % 2 == 0)
    {
        digits[n - 1] = '0';
    }
    return addOne + countAndReplace(digits, n - 1);
}

int main()
{

    std::string digits;

    std::cin >> digits;

    std::cout << countAndReplace(digits, digits.size()) << '\n';

    std::cout << digits << '\n';

    return 0;
}

首先,我们需要从标准输入中读取数字,最好使用std :: string,因为我们不预先知道数字的数量。然后,我们调用具有两个参数的递归函数-对数字字符串的引用(用于任务的第二部分,用于更改数字的位置),以及该字符串的长度。在该函数中,我们还针对每个数字检查是否需要根据您发布的规则进行替换,如果确实需要替换,我们为什么要进行替换,因此为什么要使用对字符串的引用作为参数。

这是一个非常简单的问题。请下次,在寻求帮助之前,尝试自己解决作业。否则,您将无法进行进度。

答案 1 :(得分:1)

您可以简单地使用std::unordered_map来跟踪唯一整数的数量。这是一个示例实现:

#include <iostream>
#include <unordered_map>

int main() {
  std::unordered_map<int, int> numbs;
  int numb;
  while (std::cin >> numb) {
    if (numb % 2 == 0) {
      ++numbs[0];
    }
    else {
      ++numbs[numb];
    }
  }
  for (const auto p : numbs) {
    std::cout << p.first << " was seen " << p.second  << " time(s) " << std::endl;
  }
  return 0;
}

输入:

1 2 3 4 6 5 7 4 2 5 7 5

输出:

5 was seen 3 time(s)
3 was seen 1 time(s)
1 was seen 1 time(s)
7 was seen 2 time(s)
0 was seen 5 time(s)

请注意++numbs[0]部分。如您所见,在此示例中,我们不检查键numbs中是否存在密钥,我们仅将其增加一个即可。这是因为当我们使用[numb]时,会创建一个具有该键的对象(如果该键尚不存在),并且由于int的默认初始化为{{1} }。

答案 2 :(得分:0)

该程序将完成您需要的操作,但是您实际上不需要任何递归操作。如果您不知道,递归函数就是一个调用自身的函数。例如,计算阶乘将使用递归函数:

<option value="24H">24H</option>
<option value="ALJZ">AL JAZEERA</option>

这是什么,它是从用户那里获取输入,然后循环遍历字符串中的每个字符。如果是#include <iostream> #include <string> int main() { std::string input; std::cout << "User Enter: "; std::cin >> input; int num8 = 0; int num5 = 0; for (std::string::size_type i = 0; i < input.size(); ++i) { if (input[i] == '8') { num8++; } if (input[i] == '5') { num5++; } if (input[i] == '2' || input[i] == '4' || input[i] == '6' || input[i] == '8') { input[i] = '0'; } } std::cout << "Count of 5 & 8: " << num5 + num8 << std::endl; std::cout << "Replace Even : " << input << std::endl; } 8,则会增加一个计数器。同时,它检查字符以查看它是否为偶数(5246),如果是,则将其替换为8。最后,它输出输出。

答案 3 :(得分:0)

在这里,我建议使用std::string类及其许多功能来处理字符序列,这比编写自己的算法要容易得多。

递归的关键是3部分:

  1. 定义不处理匹配字符的基本情况
  2. 定义一个处理首次出现的匹配字符的递归案例
  3. 定义一个递归用例,在满足第2部分之后继续搜索字符串的其余部分。

适用于任何长度的输入。

#include <iostream>
#include <string>

int numChars(char, std::string, int);

std::string replaceEvenWithZero(std::string);

int main()
{
    std::string str;

    std::cout << "User Enter: ";
    std::cin >> str;

    // Display the number of times the '5' or '8' appear in the string.
    std::cout << "Count of 5 & 8: " << numChars('5', str, 0) + numChars('8', str, 0) << " times.\n";

    std::cout << "Replace even with 0: " << replaceEvenWithZero(str) << std::endl;

    return 0;
}

int numChars(char search, std::string str, int subscript)
{
    if (subscript >= str.length())
    {
        // Base case: end of the string was reached.
        return 0;
    }
    else if (str[subscript] == search)
    {
        // Recursive case: A matching character was found. Return
        // 1 plus the number of times the search character appears
        // in the string.

        return 1 + numChars(search, str, subscript + 1);
    }
    else
    {
        // Recursive case: A character that does not match the search
        // character was found. Return the number of times the search
        // character appears in the rest of the string.

        return numChars(search, str, subscript + 1);
    }
}

std::string replaceEvenWithZero(std::string str) 
{
    // check the index (position) of each character in the string
    for (int i=0; i < str.length(); i++){
        // if the index even number position
        // (divides by 2 with no remainder, then true)
        // replace character with `0` at this index
        if (i % 2 != 0){
           str = str.substr(0,i-1) + "0" + str.substr(i, str.length());
        }
    }
    return str; // return our newly created string with `0`s
} 

演示:

User Enter: 4585
Count of 5 & 8: 3 times.
Replace even with 0: 0505

User Enter: 6856756453
Count of 5 & 8: 4 times.
Replace even with 0: 0806050403

答案 4 :(得分:0)

其他人通过使用与您的代码不同的签名的解决方案来回答您的问题:

int countThreeFives(int num);
int replaceEven(int num);

和/或简单地抛弃递归要求。另外,您指定了int,但仍要求用户输入一个正数-如果您的代码确实仅适用于正数,则应考虑使用unsigned int而不是int。或者只处理负数。解决所有这些问题,并保持原始代码的精神:

#include <iostream> 
using namespace std;

int countThreeFives(int number) {

    if (number != 0) {

        int count = 0, digit = abs(number % 10);

        if (digit == 5 || digit == 8) {
            count++;
        }

        return count + countThreeFives(number / 10);
    }

    return 0;
}

int replaceEven(int number) {

    if (number != 0) {
        int digit = (number % 10) * (number % 2);

        return ((number > 0) ? 1 : -1) * (replaceEven(abs(number) / 10) * 10 + digit);
        }

    return number;
}

int main() { 
    int number;

    cout << "Enter a number: "; 
    cin >> number;

    cout << "The count of 8 & 5 is: " << countThreeFives(number) << endl;
    cout << "Replacing even with 0: " << replaceEven(number) << endl;
}

示例用法显示负数支持:

> ./a.out
Enter a number: -382135
The count of 8 & 5 is: 2
Replacing even with 0: -300135
>

但是,您的两个函数使用int作为参数并返回int时,还有其他一些问题。例如,您的示例:

User enter: 4585
Count of 5 & 8: 3
Replace even with 0: 0505

错误,因为使用整数替换的数字将是:

> ./a.out
Enter a number: 4585
The count of 8 & 5 is: 3
Replacing even with 0: 505
Mac-mini>

即没有前导零。使用非数字方法只能得到前导零。使用整数的另一个问题是输入数字的长度受到限制。通常,最大长度输入为:

> ./a.out
Enter a number: 356756453
The count of 8 & 5 is: 3
Replacing even with 0: 350750053
>

再说一次,您将需要使用较大的整数类型(例如unsigned long long)或再次采用非数字方法。