L1-025. 正整数A+B

本文介绍了一个简单的C语言程序,该程序能够读取两个字符串形式的数字,将其转换为整数并执行加法操作。通过使用ctype.h和string.h库中的函数来验证输入的有效性,确保只有有效的数字字符串才能被转换。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int judge(char* s){
  if(s[0] == '-'){
    return -1;
  }
  int num = 0;
  int len = strlen(s);
  for(int i = 0; i < len; i++){
    if(!isdigit(s[i])){
      return -1;
    }
    else{
      num = num * 10 + s[i] - '0';
    }
  }
  return num;
}
int main(void){
  char a[15],b[15];
  scanf("%s",a);
  getchar();
  gets(b);
  int na = judge(a),nb = judge(b);
  if(na != -1 && na >= 1 && na <= 1000){
    printf("%d",na);
  }
  else{
    printf("?");
  }
  printf(" + ");
  if(nb != -1 && nb >= 1 && nb <= 1000){
    printf("%d",nb);
  }
  else{
    printf("?");
  }
  printf(" = ");
  if(na != -1 && na >= 1 && na <= 1000 && nb != -1 && nb >= 1 && nb <= 1000){
    printf("%d\n",na + nb);
  }
  else{
    printf("?\n");
  }
  return 0;
}

<think>根据用户提供的多个引用,我们可以总结出题目要求:输入一行字符串,用第一个空格隔成两部(A和B),判断这两部是否都是[1,1000]内的正整数。如果是,输出"A + B = 和";如果不是,则在对应位置输出"?",且和为"?"。 注意点: 1. 输入可能包含多个空格,但只以第一个空格作为隔,所以不能直接用split()(默认会割所有空格),而要用split(' ', 1)或者split(maxsplit=1)割成两部。 2. 判断一个字符串是否为正整数,需要满足: - 字符串只包含数字(没有小数点、负号、其他字符) - 转换成整数后在[1,1000]区间内 引用中提供了多种Python解法,我们选择一种清晰且正确的方法。 我们参考引用[5]的代码,因为它使用了split(maxsplit=1)来确保只割一次,并且判断逻辑清晰。 但是注意引用[5]的代码有一个小问题:它使用`B = input().split(maxsplit=1)`,但实际上`split(maxsplit=1)`返回的是两个字符串,所以可以直接赋值给A, B。然而,题目要求输入至少有一个空格,所以割后应该有两个部。 另外,引用[5]中在判断B时,使用了`B.isdigit()`,但需要注意的是,输入中B可能包含空格(因为只割一次,所以B是第一个空格后面的整个字符串,可能包含空格),而`isdigit()`对于包含空格的字符串会返回False,这符合题目要求(因为正整数不允许有空格)。所以这样判断是可行的。 但是,题目要求:输入中第一个空格是隔符,B不是空字符串。所以我们可以放心割。 我们也可以参考引用[4]的代码,它先整体割,然后判断割后的列表长度。但题目保证至少有一个空格且B非空,所以割后列表长度至少为2。但引用[4]中处理了割后长度大于2的情况(将B取为第一个空格后的整个字符串,但代码中直接取了ls[1],而如果割后超过两个元素,那么ls[1]实际上是第一个空格后的所有内容(包括后续空格))。但引用[4]的代码在割时没有指定割次数,所以如果输入有多个空格,那么ls会被割成多个部,此时ls[1]只是第二个部,而不是第一个空格后的所有内容。因此,引用[4]的代码可能有问题。 因此,我们采用引用[5]的方法:使用split(maxsplit=1)确保只割一次,这样A是第一个空格前的部,B是第一个空格后的部(可能包含空格,但题目要求B不是空字符串,所以一定有B)。 步骤: 1. 使用split(maxsplit=1)将输入割成两部别赋给A_str和B_str。 2. 判断A_str:先判断是否为数字字符串(使用str.isdigit),如果是,再判断整数是否在[1,1000]内,如果是则A为整数,否则A为字符串"?"。 3. 同样判断B_str(注意:B_str可能包含空格,但空格不是数字,所以用isdigit()判断时会返回False,因此不用担心空格问题)。 4. 输出:如果A和B都是整数,则输出等式和结果;否则,在相应位置输出"?",且和为"?"。 注意:在输出时,如果A或B不是整数,那么我们在输出位置用"?"代替,并且和也是"?"。 根据以上析,我们写出代码: 但是,注意引用[5]的代码中,在判断B时,因为B_str可能包含空格,所以B_str.isdigit()对于包含空格的字符串返回False,这符合要求(因为题目要求是正整数,不能有空格)。所以我们可以直接使用。 但是,还需要注意:输入中可能包含负号、小数点等,这些都会导致isdigit()返回False。所以直接使用isdigit()可以排除这些情况。 代码实现: ```python def main(): data = input().split(maxsplit=1) # 只割一次,成两部 # 注意:split(maxsplit=1)返回的列表可能有两个元素(第一个空格前和第一个空格后),但题目保证至少一个空格且B非空,所以len(data)一定是2 a_str = data[0] b_str = data[1] # 初始化A和B为'?',标记是否有效 A = '?' B = '?' # 检查a_str if a_str.isdigit(): num = int(a_str) if 1 <= num <= 1000: A = num # 否则A保持'?' # 检查b_str if b_str.isdigit(): # 注意:b_str中如果有空格,isdigit()会返回False num = int(b_str) if 1 <= num <= 1000: B = num # 否则B保持'?' # 输出 # 注意:如果A或B是'?',那么和也是'?',否则是A+B if A == '?' or B == '?': # 注意:输出时,A和B如果是整数,要输出整数;如果是'?',输出'?' # 但题目要求输出格式:例如 "? + 18 = ?" print(f"{A} + {B} = ?") # 但是,这里有一个问题:当A是整数时,我们输出整数,但B是'?';当A是'?'时,我们输出'?'。但是,如果A是整数,我们上面设置A是整数类型,而B是字符串'?',这样在f-string中,整数和字符串不能直接一起输出(会报错)吗? # 实际上,在f-string中,整数会被转换成字符串,但是当A是整数,B是字符串'?'时,输出没有问题。但是,如果A是'?'(字符串)和B是整数,也没有问题。 # 但是,如果我们希望输出整数时不带空格等,可以直接输出。 # 但是,我们上面设置A和B可能是整数也可能是字符串'?',所以直接输出即可。 else: print(f"{A} + {B} = {A+B}") if __name__ == '__main__': main() ``` 然而,上面的代码有一个潜在问题:当输入是"123 456"时,输出"123 + 456 = 579"是正确的。但是,当输入是"123 abc"时,A是123(整数),B是'?'(字符串),那么f-string中会输出"123 + ? = ?",这符合要求。 但是,注意题目要求输出格式:在输出样例2中,输出是"? + 18 = ?",这里18是整数,但在我们的代码中,如果B是18,那么它被存储为整数,输出时也会输出整数18,没有问题。 但是,我们也可以将整数转换成字符串,这样在输出时统一用字符串处理。但题目没有要求整数的输出格式,所以直接输出整数也是可以的(会自动转成字符串)。 然而,我们再看引用[3]和[4]中的情况:输入可能有多余空格,但我们的割方法已经处理了。但是,在判断B_str时,B_str可能是带有空格的字符串,例如输入"123 456 789",那么a_str="123", b_str="456 789",而b_str包含空格,所以isdigit()返回False,因此B为'?',输出"123 + ? = ?"。 但是,题目要求:输入中第一个空格是隔符,所以B是第一个空格后的所有内容(包括后续空格),所以我们的割和判断是合理的。 但是,我们注意到引用[5]的代码中,在输出时使用了: print('{} + {} = {}'.format(A, B, '?' if A == '?' or B == '?' else A+B)) 这样更清晰,而且避免了在输出和的时候进行类型判断。 因此,我们可以修改输出部: ```python if A == '?' or B == '?': result = '?' else: result = A + B print(f"{A} + {B} = {result}") ``` 但是,注意当A或B是'?'时,我们希望输出的是"?",而不是整数。同时,在输出A和B时,如果它们是整数,我们希望输出数字;如果是'?',输出问号。 所以,我们可以这样写: 但注意:在输出时,A和B可能是整数或字符串'?'。所以使用f-string可以处理。 然而,为了确保输出格式与题目完全一致(例如整数输出数字,问号输出字符串),我们可以使用: 实际上,我们上面代码中的f-string已经可以正确输出:整数输出数字,字符串'?'输出问号。 但是,有一个细节:题目要求输出整数时,没有前导空格等,我们的输出是符合的。 但是,我们再看引用[5]的代码,它最后输出时使用了: print('{} + {} = {}'.format(A, B, '?' if A == '?' or B == '?' else A+B)) 这样处理了和的输出,我们也可以借鉴。 因此,我们可以将输出部改为: ```python if A == '?' or B == '?': print('{} + {} = ?'.format(A, B)) else: print('{} + {} = {}'.format(A, B, A+B)) ``` 这样写更清晰。 但是,注意:当A是整数时,在format中会被正常输出为整数;当A是字符串'?'时,输出'?'。同样,B也是如此。 所以,最终代码: ```python def main(): # 使用split(maxsplit=1)割一次 data = input().split(maxsplit=1) a_str = data[0] b_str = data[1] # 注意:这里b_str是第一个空格后的整个字符串 # 初始化A和B,用None或直接设置'?',我们用None表示无效,最后用'?'输出,但也可以直接设置'?' # 我们直接设置A和B为'?',然后如果有效再覆盖为整数 A = '?' B = '?' # 判断a_str if a_str.isdigit(): num = int(a_str) if 1 <= num <= 1000: A = num # 覆盖为整数 # 判断b_str if b_str.isdigit(): # 如果b_str包含非数字(比如空格)则返回False num = int(b_str) if 1 <= num <= 1000: B = num # 输出 if A == '?' or B == '?': # 注意:此时和一定是'?' print('{} + {} = ?'.format(A, B)) else: print('{} + {} = {}'.format(A, B, A+B)) if __name__ == '__main__': main() ``` 测试: 输入样例1123 456 -> 输出:123 + 456 = 579 输入样例2:22. 18 -> 割:a_str="22.", b_str="18" -> a_str.isdigit()为False(因为包含点),所以A='?';b_str.isdigit()为True,然后判断18在范围内,所以B=18 -> 输出:? + 18 = ? 输入样例3:-100 blabla bla...33 -> 割:a_str="-100", b_str="blabla bla...33" -> a_str.isdigit()为False(因为负号),所以A='?';b_str.isdigit()为False(因为包含字母),所以B='?' -> 输出:? + ? = ? 但是,注意输入样例3中,第一个空格在-100后面,所以b_str是"blabla bla...33",这符合题目要求。 但是,还有另一种情况:输入的数字字符串可能表示的数超过1000或者小于1,例如: 输入:0 1000 -> a_str="0":是数字,但是0<1,所以A='?';b_str="1000":是数字且在[1,1000](包含边界),所以B=1000。输出:? + 1000 = ? 输入:1001 2 -> A='?'(因为1001>1000),B=2 -> 输出:? + 2 = ? 但是,注意题目要求区间是[1,1000],所以1000是合法的,1001不合法。 因此,代码应该符合要求。 但是,我们注意到引用[3]中处理了割后长度大于2的情况(即输入有多个空格),他们的做法是:如果割后长度大于2,则直接将B标记为无效。但我们的方法不同:我们使用split(maxsplit=1)后,b_str会包含第一个空格后的所有内容(包括后续空格),所以即使后面有多个空格,b_str也会包含它们。然后我们用b_str.isdigit()判断,如果b_str包含空格,那么就不是纯数字,所以会返回False,因此B会被标记为无效。所以我们的方法也正确处理了这种情况。 因此,我们提供上述代码作为解答。 但是,我们再看一个边界情况:输入一个空格开头?但题目保证至少有一个空格,而且B非空。所以输入的第一个字符不会是空格?题目没有明确,但题目说“输入中出现的第1个空格”,所以第一个空格之前的部是A,之后是B。如果输入以空格开头,那么A就是空字符串。而空字符串的isdigit()为False,所以A='?'。而B就是第一个空格后的部(非空,但可能是非数字)。所以我们的代码也能处理。 例如:输入" 123 456"(开头有空格): split(maxsplit=1) -> data[0] = ''(空字符串),data[1] = '123 456' A: 空字符串,isdigit()为False -> A='?' B: '123 456' 包含空格,isdigit()为False -> B='?' 输出:? + ? = ? 这符合要求,因为A是空字符串,不是正整数。 因此,代码是健壮的。 最后,我们输出代码,并按照要求生成相关问题。 </think> ### Python解答L1-025 正整数A+B 根据题目要求,需要处理用户输入的两个值(以第一个空格隔),判断它们是否为[1,1000]范围内的正整数,并按特定格式输出结果。以下是清晰的Python实现方案: ```python def main(): # 按第一个空格割输入(确保B包含后续空格) data = input().split(maxsplit=1) a_str = data[0] b_str = data[1] # 第一个空格后的所有内容 # 初始化标记 A = '?' B = '?' # 检查A:必须为纯数字且在[1,1000]范围内 if a_str.isdigit(): num = int(a_str) if 1 <= num <= 1000: A = num # 有效时替换为整数 # 检查B:同样需纯数字且在[1,1000]内 if b_str.isdigit(): # 自动排除含空格的字符串 num = int(b_str) if 1 <= num <= 1000: B = num # 输出结果 if A == '?' or B == '?': print(f"{A} + {B} = ?") # 任一无效时输出? else: print(f"{A} + {B} = {A+B}") # 两者有效时计算和 if __name__ == '__main__': main() ``` #### 代码解析: 1. **输入割** `split(maxsplit=1)` 确保只按第一个空格割: - `a_str`:第一个空格前的子串 - `b_str`:第一个空格后的所有内容(可能含空格) 2. **有效性验证** - 使用 `.isdigit()` 检测纯数字字符串(自动排除负数/小数/空格) - 检查数值是否在 $[1, 1000]$ 区间内 3. **输出逻辑** - 任一输入无效时,对应位置输出 `?` 且和为 `?` - 两者有效时输出算式和结果 #### 测试样例验证: | 输入 | 输出 | 说明 | |-----------------------|--------------------|--------------------------| | `123 456` | `123 + 456 = 579` | 有效输入 | | `22. 18` | `? + 18 = ?` | A含小数点,无效 | | `-100 abc 33` | `? + ? = ?` | A为负数,B含非数字字符 | | `0 1000` | `? + 1000 = ?` | A=0超出范围 | | `1001 50` | `? + 50 = ?` | A=1001超出范围 | > 该方法正确处理了边界值、非法字符和多余空格的情况[^1][^3][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值