我把这个作业作为家庭作业,我无法弄清楚如何做到这一点:
输入是数字1,2和3的字符串 您需要构建一个函数来确定字符串表示的数字是否可以被3整除。
规则:
- 没有循环。
- 数字上没有数学运算(+, - ,*,/,%)。
- 使用递归。
提示:如果数字的总和可以被3整除 - 那么数字也是。
我尝试使用提示来提出算法来执行此操作,但它不起作用(如果1和2出现相同的次数,则数字可以被3整除。但是如果数字组成则只有1或2它仍然可以被整除,我们再次遇到同样的问题)。
有什么想法吗?
答案 0 :(得分:3)
divBy3_0
,只需用字符串调用它。
bool divBy3_0(char const *n);
bool divBy3_1(char const *n);
bool divBy3_2(char const *n);
bool divBy3_0(char const *n) {
switch(*n) {
case '1': return divBy3_1(&n[1]);
case '2': return divBy3_2(&n[1]);
case '3': return divBy3_0(&n[1]);
}
return true;
}
bool divBy3_1(char const *n) {
switch(*n) {
case '1': return divBy3_2(&n[1]);
case '2': return divBy3_0(&n[1]);
case '3': return divBy3_1(&n[1]);
}
return false;
}
bool divBy3_2(char const *n) {
switch(*n) {
case '1': return divBy3_0(&n[1]);
case '2': return divBy3_1(&n[1]);
case '3': return divBy3_2(&n[1]);
}
return false;
}
答案 1 :(得分:2)
基于递归和二进制加法(不含+-/*%
)
sum_str_digits
)检查是否可以通过3(is_dividable_by_3
)分割:
示例代码,当然需要小心(特别是错误处理)
#include <stdio.h>
#include <stdlib.h>
int badd(int n1, int n2){
int carry, sum;
carry = (n1 & n2) << 1;
sum = n1 ^ n2;
if (sum & carry)
return badd(sum, carry);
else
return sum ^ carry;
}
char * int_to_str(int n) {
//int length_0 = snprintf( NULL, 0, "%d", n) + 1;
int length_0 = 32;
char* str = malloc(length_0);
snprintf( str, length_0, "%d", n);
return str;
}
int digit_to_int(char d) {
char str[2];
str[0] = d;
str[1] = '\0';
return (int) strtol(str, NULL, 10);
}
int sum_str_digits(char * s, int sum){
sum = badd(sum, digit_to_int(s[0]));
if (s[1] == '\0') {
printf("Sum: %d \n", sum);
return sum;
}
return sum_str_digits(&(s[1]), sum);;
}
int is_dividable_by_3(int n) {
switch (n) {
case 3:
case 6:
case 9:
return 1;
case 1:
case 2:
case 4:
case 5:
case 7:
case 8:
case 0:
return 0;
default: {
char * str = int_to_str(n);
int x = sum_str_digits(str, 0);
free(str);
return is_dividable_by_3(x);
}
}
}
int main(int argc, char *argv[]){
int sum;
sum = sum_str_digits(argv[1], 0);
printf("Is div by 3: %d \n", is_dividable_by_3(sum));
return 0;
}
发布时间编辑 - 以前的版本
在二进制模式下递归减去3(不使用任何被禁止的数学运算符),直到等于3或更小:
int badd(int n1, int n2){
int carry, sum;
carry = (n1 & n2) << 1; // Find bits that are used for carry
sum = n1 ^ n2; // Add each bit, discard carry.
if (sum & carry) // If bits match, add current sum and carry.
return badd(sum, carry);
else
return sum ^ carry; // Return the sum.
}
int bsub(int n1, int n2){
// Add two's complement and return.
return badd(n1, badd(~n2, 1));
}
int idiv3(int n) {
if (n == 3) {
return 1;
}
if (n < 3) {
return 0;
}
if (n > 3) {
return idiv3(bsub(n, 3));
}
}
int div3(const char *n) {
return idiv3(strtol(n, (char **) NULL, 10));
}
答案 2 :(得分:1)
这个应该有效。它通过从3开始循环到数字来代替从数字中连续减去3,保持循环计数器并递归调用自身。 count++
确实使用了某些&#34; +&#34;字符,但不是&#34; +&#34;操作员而不是数字:
int f(int num){
int count = 0, i;
if(num == 3){
puts ("number is divisible by 3");
}
else if(num < 3){
puts ("number is not divisible");
}
else{
for (i = 3; i < num; i++){
count++;
}
num = count;
f (num);
}
}
void g (char *s) {
f (atoi (s));
}
典型的&#34;编写程序而不编写程序&#34;分配。我有点害怕你从实用编程中学到很多东西。 (除了如何使用只允许使用该语言子集的愚蠢程序来浪费计算资源。)
答案 3 :(得分:0)
我认为只要使用递归构建的总和,就允许对sum
进行模数操作。它可能如下所示:
#include <stdio.h>
#include <stdlib.h>
int isDividableBy3_recursive(const char* n, int sum) {
if (!n || !*n) {
return (sum % 3 == 0) ? 1 : 0;
}
else {
return isDividableBy3_recursive(n+1, sum+(*n - '0'));
}
}
int isDividableBy3(const char* n) {
return isDividableBy3_recursive(n,0);
}
int main(int argc, char *argv[]){
char* testNumbers[] = { "100", "233", "345", "3", "", NULL };
for (int i=0;testNumbers[i]!=NULL;i++) {
char* testNumber = testNumbers[i];
printf("%s dividable by 3:%d\n", testNumber, isDividableBy3(testNumber));
}
return 0;
}
答案 4 :(得分:0)
这里的问题是,计算机完成的所有事情都是数学运算。所以我提交一个编译器应该优化的跳转表。这是&#34; Olafesque兼容&#34;溶液
switch (the_damn_number)
{
case 0:
return true;
case 1: case 2:
return false;
case 3:
return true;
// and so on
case largest_number_I_care_about:
// ToDo
}
(如果您不允许将字符串转换为if
种类型,请使用switch
块。)
使用您喜欢的脚本工具为您生成代码。
答案 5 :(得分:-1)
这是你怎么做的。
您的第一份工作是使用unsigned long long int strtoull(const char *nptr, char **endptr, int base);
将字符串转换为unsigned long long
。然后将其应用于
bool is_divisible_by_3(unsigned long long n)
{
if (n > 9){
// more than one digit
return is_divisible_by_3(sum_digits_in_number(n));
} else {
return n == 0 || n == 3 || n == 6 || n == 9;
}
}
您需要构建sum_digits_in_number(unsigned long long)
:如果不使用+
,/
或%
,在这里&#39,您很难看到如何做到这一点;否则就是一种方式:
sum = 0;
while (n) {
sum += n % 10;
n /= 10;
}