7-5 字串轉換成十進位制整數 (15 分) 測試點 2 測試
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就說不足以證明字串特徵