题意:
给定一段描述, 从中分析出所给的条件是 P、U、I 中的某两项, 然后根据公式 P=U*I 计算出所缺的另一项.
思路:
1. 先在字符串中分别查找 P=、U=、I=;
(1). 若找到 P=, 则往后遍历, 直至找到第一个 W(P的单位) 为止, 然后往前一位看是否为 W 的前缀 m, 若是, 则取为 1.0 / 1000;
(2). 若找到 U=, 则往后遍历, 直至找到第一个 V(U的单位) 为止, 然后往前一位看是否为 V 的前缀 k, 若是, 则取为 1000;
(3). 若找到 I=, 则往后遍历, 直至找到第一个 A(I的单位) 为止, 然后往前一位看是否为 A 的前缀 M, 若是, 则取为 1000000;
2. 若找到 P、U, 则使用公式 I = P/U; 若找到 P、I, 则使用公式 U = P/I; 若找到 U、I, 则使用公式 P = U*I.
要点:
1. %.2f 输出两位小数.
2. atof 转 string 为 double.
3. 表达式的结尾下标就是从P=、U=、V=找到其相应的单位(W、V、A),不能是说找到第一个空格,否则下面的例子会出错:
I=-1e-2A and U=2e3V
xx xx x I=0.0000000000000001MA yy yy U=1000000000000000.0000000mV zz
U=200VI=4.5A.
4. 1/1000 会返回0, 即使写在 double(1/1000) 也一样; 若想得到 0.001, 必须写成 1.0/1000.
5. 不能直接写 string head = 'P' + "="; 也不能写成 string head = "p" + "="; 因为 'P' 是 char 类型, "="是const char[2] 类型(注意不是string类型), 而这两者都是没有重载.
题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=478
代码:
# include <iostream> # include <string> # include <cstdio> # include <cstring> # include <vector> # include <algorithm> # include <stdlib.h> // atof using namespace std; // 根据一个表达式获取其单位前缀, 即表达式从后往前数一位, 如果是 m, k, M 就是有前缀, 否则返回 -1 double getPrefix(const string line, int lastPos){ switch(line[lastPos-1]){ case 'm': // 这里不能直接写成 1/1000, 否则会转化成 0, 导致好几次 WA, 必须直接写成 1.0/1000 return 1.0/1000; case 'k': return 1000; case 'M': return 1000000; default: return 1; } } // 获取 P, U, I 的值, 若未找到, 则返回 -1 double getConcept(const string line, char concept, char unit) { // 这里不能直接写成 string head(concept); string head(1, concept); head += "="; // string head = concept + "="; // 表达式的起始下标就是 P= 或 U= 或 I= size_t conceptHead = line.find(head); if(conceptHead == string::npos){ return -1; } // 表达式的结尾下标就是从 表达式起始 开始找到的第一个 unit size_t conceptTail = line.find(unit, conceptHead); double prefix = getPrefix(line, conceptTail); string number; if(1 == prefix){ // 没有前缀 number = line.substr(conceptHead+2, conceptTail-conceptHead-2); }else{ // 有前缀 number = line.substr(conceptHead+2, conceptTail-conceptHead-3); } return atof(number.c_str()) * prefix; } // 根据读入的字符串获得结果 string getSolution(const string line) { // 分别获取 P,U,I, 若不存在, 则返回 -1 double P = getConcept(line, 'P', 'W'); double U = getConcept(line, 'U', 'V'); double I = getConcept(line, 'I', 'A'); char solution[20]; if(-1 == P){ sprintf(solution, "P=%.2lfW", U*I); }else if(-1 == U){ sprintf(solution, "U=%.2lfV", P/I); }else if(-1 == I){ sprintf(solution, "I=%.2lfA", P/U); }else{ return "error"; } return solution; } int main(int argc, char const *argv[]) { #ifndef ONLINE_JUDGE freopen ("537_i.txt", "r", stdin); freopen ("537_o.txt", "w", stdout); #endif int caseNum = 0; cin >> caseNum; cin.ignore(); // 必须有这行,否则下面 getline 会读到空行 for(int i=0; i<caseNum; i++){ string line; getline(cin, line); string solution = getSolution(line); cout << "Problem #" << i+1 << endl << solution << endl << endl; } return 0; }
环境:C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE