单位换算题,本质字符串的处理,原题见:
(希望不要被校友看到)
首先发现规律,’/‘后必为分母,’*'后必为分子
(然鹅比赛时我这个题意没理解对,orz)
读取第一个单位时,必为分子,需要特判
之后使用string[]数组分别读取分子分母
因为题目数据字符串长度只有1000,直接暴力枚举一个个判断是否相等就好
上代码:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
string s;
string s1[101], s2[101];//s1分子,s2分母
string a;
int lent = 1, cnt;
int main() {
cin >> s;//读入原始字符串
//s1.push_back(s[0]);
auto i = s.begin();//迭代器,从s的开头搜索。auto是让编译器自己判断变量的类型
while (*i != '*' && *i != '/') a += *i, i++;//读取第一个单位,一直到读到'/''*'停止
s1[0] = a;//将第一个单位直接丢尽分子数组
a.clear();//清空a字符串,因为之后还要继续读取
int flag1 = 0, flag2 = 0;
while (i != s.end()) {
if (!flag1 && !flag2) {//初始状态,分子分母均未标记
if (*i == '*') flag1 = 1, flag2 = 0;//‘*’号后必为分子,用flag1标记
if (*i == '/') flag2 = 1, flag1 = 0;//‘/’后必为分母,用flag2标记
}
else if (flag1 || flag2) {
if (*i == '*' && flag1 == 1) s1[lent++] = a, a.clear(), flag1 = 1, flag2 = 0;
//'*'号前是分子(flag1=1),所以将a丢尽分子数组,清空a,乘号后也是分子,flag1标记
else if (*i == '*' && flag2 == 1) s2[cnt++].assign(a), a.clear(), flag2 = 0, flag1 = 1;
//'*'号前是分母(flag2=1),所以将a丢尽分母数组,清空a,乘号后是分子,flag1标记
else if (*i == '/' && flag1 == 1) s1[lent++] = a, a.clear(), flag1 = 0, flag2 = 1;
//‘/’同理不写了
else if (*i == '/' && flag2 == 1) s2[cnt++].assign(a), a.clear(), flag2 = 1, flag1 = 0;
else a += *i;//如果没有读取到‘/’‘*’,那就将让a存储单位
}
i++;
}//压行狂魔
//printf("flag1 = %d,flag2 = %d\n",flag1,flag2);
//最后一个单位的读入
if (flag2) s2[cnt++] = a;
else if (flag1) s1[lent++] = a;
//for (int i=0;i<=lent;)
int len = max(lent - 1, cnt - 1);
for (int j = 0; j <= len; j++) {
for (int t = 0; t <= len; t++)
if (s1[j] == s2[t]) s1[j] = " ", s2[t] = " ";//如果相等,将相等的单位清空
}
int flag3 = 0, flag4 = 0;//用来标记字符串数组是否全部为空
int t1 = 0;
sort(s1, s1 + lent);//根据字符串大小排序
while (s1[t1] == " ") t1++;//从第一个非空字符串开始
//printf("t1 = %d\n",t1);
if (t1 < lent) cout << s1[t1], flag3 = 1;//先输出第一个单位,只要有一个字符串不为空,就将flag3=1
for (int j = t1 + 1; j < lent; j++)
if (s1[j] != " ") cout << '*' << s1[j], flag3 = 1;//用乘号连接
if (!flag3) cout << "1";//如果flag3一直为0,说明没有输出任何字符串,根据题目要求,输出1
cout << endl;//换行
int t2 = 0;//分母输出逻辑同上
sort(s2, s2 + cnt);
while (s2[t2] == " ") t2++;
if (t2 < cnt) cout << s2[t2], flag4 = 1;
for (int j = t2 + 1; j < cnt; j++)
if (s2[j] != " ") cout << '*' << s2[j], flag4 = 1;
if (!flag4) cout << "1";
cout << endl;
}
总结一下string的用法
string s[20] 意思是开了二十个字符串
在此定义下,不能使用:
s.find() 错误
strcmp() 错误
等等针对字符的操作,都会报错。
直接将每个数组当成字符串。
判断是否相等直接使用 ==
赋值的时候也需要赋值字符串而不是字符
(也就是必须用双引号"",而不能使用单引号’ ')
可以使用sort()进行字符串大小排序(注意在sort(a.begin(),a.end())中,a.end()取不到,经典前闭后开)
同时,以下输入输出也需要注意:
// String类.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string s[20];
//cin>>s;//error
cin >> s[0];//true
cin >> s[1];
//auto i = s.begin();//error
auto i = s[0].begin();
//cout<<i<<endl;//error
cout << *i << endl;//输出s[0]的第一个字符
sort(s[0].begin(), s[0].end());//将s[0]中的字符按照字典顺序排序
auto j = s[0].find('A');
if (j != s[0].npos) cout << j << endl; //如果找到,输出字符A在s[0]中的位置
else cout << -1 << endl;//如果没找到,输出-1
cout << s[0] << endl;
//printf("%s\n",s[0]);//error
//printf("%s",*s);//error
//cout<<s[0]<<endl;//true
cout << s << endl;//输出地址
cout << *s << endl;//输出字符串s[0]
cout << *(s + 1) << endl;//输出字符串s[1]
printf("................\n");
sort(s, s + 2);//将全部字符串按照字符串大小排序 ,前闭后开,s+2取不到
cout << *s << endl;//输出字符串s[0]
cout << *(s + 1) << endl;//输出字符串s[1]
printf("................\n");
cout << s[0] << endl;
cout << s[1] << endl;
//auto q = s.begin();//error
auto* w = s;
cout << *w << endl;//输出字符串s[0]
cout << *(w + 1) << endl;//输出字符串s[1]
//puts(s);//error
}