7-5 字符串转换成十进制整数 (15 分) 测试点 2 测试

版权声明:如果是原创仅供参考,转请标明出处。 https://blog.csdn.net/oShuaiFeng/article/details/83954336

7-5 字符串转换成十进制整数 (15 分)

输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。

输入格式:

输入在一行中给出一个以#结束的非空字符串。

输出格式:

在一行中输出转换后的十进制数。题目保证输出在长整型范围内。

输入样例:

+-P-xf4+-1!#

输出样例:

-3905

前提:测试点有三个 编号分别是 0 1 2 

测试点 2 的特征是    长度为 16可见字符 其中第八位是 负号 其余位置均为非法字符的字符串。就是说 整个字符串中只有负号是十六进制判断中的合法字符 ,其余的都不合法!!!!! 

模拟输入样例:!!!!!!!!-!!!!!!!#

模拟输出样例:0

我一共写了三种代码  第一种 不经意绕开了 正确我们来看一下第一种绕开法: (C++)

#include <bits/stdc++.h>

using namespace std;

string tmp;

void Input() {
	getline(cin, tmp);
	char* s = strstr(&(tmp[0]), "#");
	*s = 0;
}

bool ISSIX(char x) {
	if (x >= 'A' && x <= 'Z') x += 32;
	if (x >= '0' && x <= '9') return true;
	if (x >= 'a' && x <= 'f')
		return true;
	return false;
}

int main() {

	Input();
	bool lock = true; // 锁
	int first=-0x3f3f3f3f;

	char* t = &(tmp[0]);
	string JG = "";
	for (int i = 0, j = strlen(t); i < j; i++) {
		bool f = ISSIX(t[i]);
		if (f != false) {
			JG += t[i];
			if (lock) {
				lock = false;
				first = i;
			}
		}
	}
	if (strstr(t, "-") - t < first) { // 编号 1
		printf("-");
	}
	long long int ft = strtoll(JG.c_str(), NULL, 16);

	printf("%lld", ft);

	system("pause");
	return 0;

}

我们知道 strstr 找到返回待查找字符串首字母在源字符串的一个地址。找不着返回NULL 。NULL是什么东西 NULL 就是 0 

所以 以上 编号 1 处 不会发生意外情况崩溃。最多减出负数。 而在第三个测试点中,first 从头到尾除开头手动赋值以外,均无赋值,我给了 first 一个很小值 。这个判断是正确的!!而转换字符串 JG 我初始化为空串 这也让转换函数strtoll不出错.

但我说一下 这个正确的代码目考虑到 -0 这个情况。所以是不完美的代码。

同时 批评 样例提出人 不严谨 考虑不周的问题!!这个网上一直有人认为第三个是有输入 负号和零的 结果只测出了 负号。

测试方法 文章末尾。

第二个方法: (C 语言) strstr查找标记法 + 及时转换提取法 

#include<stdio.h>
#include<string.h>
#include<math.h>
int main() {
	char a[1000];
	char b[1000] = { 0 };
	gets(a);
	a[strstr(a, "#") - a] = 0;
	for (int i = 0,k=0, j = strlen(a); i < j; ++i) {
		if (a[i] >= 'A' && a[i] <= 'Z')
			a[i] += 32;
		if ((a[i] >= 'a' &&a[i] <= 'f') || (a[i] >= '0' && a[i] <= '9') || (k == 0 && a[i] == '-')) {
			b[k++] = a[i];
		}
	}
	long long int f = strtol(b, NULL, 16);
	printf("%lld", f);
	system("pause");
	return 0;
}

第三个方法 太不堪入目了,这是一个学弟问我的,我就不贴了。

现在 我把我是怎么测试出样例的说一下  也就是符号穷举法+范围二分法

符号穷举法:把重要特殊符号出现的位置在一个字符串中找出来。方法有两种

1. 使用for() + 特殊符号   :for 控制一段很大的范围 去找 找到就 while(1); 死循环 这样超时的时候就能命中特殊符号的范围。再逐步缩小。

2.字符串较短时 可以手动 判断 一个一个枚举。

范围二分法:测试样例输入的时候 采用范围二分法 

1.输入的时候使用 一个if 把范围逐渐缩小 然后定位准确范围 模板是

if(...) while(0); 超时为 该数字范围  最后越缩越小 直接 就可以确定了

注意 随机大数据是无法测出的 注意

这是我测这道题我测试的时候的界面 分享一下  op 是手动枚举常量 不要看下面只有一个10就说不足以证明字符串特征

猜你喜欢

转载自blog.csdn.net/oShuaiFeng/article/details/83954336