HW2016_字符串_STL_DP
一、在字符串str1中删除那些在str2中出现的字符。
str2可能会有重复字符,直接遍历会导致效率低下,故先借助STL的set容器对str1查重;
然后,遍历str1和str2,对str1进行查重。
#include <iostream>
#include <string>
#include <set> using namespace std; void deleteChar(char* strRet, const string& str1,int len1, const string& str2,int len2)
{
if(len1 < ) //异常检测
{
return;
}
bool findIt = false; //查找标记位 set<char>mySet;
int i = ,j = ,k = ;
for(i = ; i < len2; ++i) //str2去重复字符
{
mySet.insert(str2[i]);
} for(j = ; j < len1; j++)
{
for(set<char>::iterator it = mySet.begin(); it != mySet.end(); ++it)
{
if(str1[j] == *it && findIt == false)
{
findIt = true;
break;
}
}//end for if(!findIt)
{
strRet[k++] = str1[j];
}
findIt = false; //标记位置位 }//end for
strRet[k] = '\0'; //c风格字符串结束标志 } int main()
{
string str1,str2;
while(cin >> str1 >> str2)
{
int len1 = str1.size();
int len2 = str2.size();
char* strRet = new char[len1 + ]; //申请空间存放查重后的字符串
deleteChar(strRet,str1,len1,str2,len2);
cout << strRet << endl;
delete strRet; //防止内存泄漏
return ;
} }
二、
编程题-成绩排名
题目总共包含如下两种格式的字符串命令:
1 LOD GRADE命令,其格式为:
LOD GRADE:NAME=XiaoMing,MATH=80,LANG=90;
(1)此命令用于导入学生成绩
(2)NAME字段表示学生姓名
(3)MATH字段表示学生数学成绩
(4)LANG字段表示学生语文成绩
(5)MATH字段和LANG字段顺序不一定是MATH在前,LANG在后
(6)相同的分数,名词相同,后面的名次孔雀:例如100,99,99,99,98,98,名次1,2,2,2,5,5
(7)此命令会连续执行,直到遇到第一个LST GRADE
2 LST GRADE命令,其格式为:
LST GRADE:NAME=XiaoHong;
(1)此命令用于查询学生成绩
(2)NAME字段表示学生姓名
(3)查询结果格式:姓名 数学 语文 总分 数学排名 语文排名 总排名
(4)每组用例,此命令仅执行一次
样例输入
LOD GRADE:NAME=XiaoMing,MATH=80,LANG=90;
LOD GRADE:NAME=XiaoHong,LANG=60,MATH=100;
LOD GRADE:NAME=XiaoMei,MATH=70,LANG=90;
LST GRADE:NAME=XiaoHong;
样例输出 XiaoHong 100 60 160 1 3 2
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdlib> using namespace std;
const string LOD = "LOD GRADE";
const string LST = "LST GRADE";
int myCout = ; class student{
public:
student(string str)
{
OPE = "";
unsigned int posOPE = str.find_first_of(':');
if( posOPE < str.size())
OPE = str.substr(, posOPE);
unsigned int posNAME1 = str.find_first_of('=');
unsigned int posNAME2 = str.find_first_of(',');
NAME = str.substr(posNAME1 + , posNAME2 - posNAME1 - ); unsigned int posEnd = str.find_last_of(';');
unsigned int posMATH = str.find_last_of('H');
unsigned int posLANG = str.find_last_of('G');
unsigned int posLastCommer = str.find_last_of(','); if(posEnd - posMATH > )
{
MATH = atoi(str.substr(posMATH + , posLastCommer - posMATH - ).c_str());
LANG = atoi(str.substr(posLastCommer + , posEnd - posLastCommer -).c_str());
}
else
{
MATH = atoi(str.substr(posMATH + , posEnd - posMATH - ).c_str());
LANG = atoi(str.substr(posLANG + , posLastCommer - posLANG - ).c_str());
} totalScore = MATH + LANG;
mathMarking = ;
langMarking = ;
totalMarking = ;
count = ;
}
~student(){}
string OPE;
string NAME;
int MATH;
int LANG;
int totalScore;
int mathMarking;
int langMarking;
int totalMarking;
int count;
};
bool mathCompare(student*& stu1, student*& stu2)
{
return (stu1->MATH > stu2->MATH) ||
(stu1->MATH == stu2->MATH && stu1->count < stu2->count); //desc ; 成绩相等,按照出现的顺序排序
}
bool langCompare(student*& stu1, student*& stu2)
{
return (stu1->LANG > stu2->LANG) ||
(stu1->LANG == stu2->LANG && stu1->count < stu2->count); //desc
} bool totalCompare(student*& stu1, student*& stu2)
{
return (stu1->totalScore > stu2->totalScore) ||
(stu1->totalScore == stu2->totalScore && stu1->count < stu2->count); //desc
} int main()
{
string str;
vector<student* >students;
while(getline(cin, str)) //去读一行,使用cin>>会有缓冲区的问题(空格,tab,回车)
{
//fill into vector
student* stu = new student(str); if(LOD == stu->OPE)
{
students.push_back(stu);
stu->count = myCout++; //用于记录学生出现的顺序
}
if(LST == stu->OPE)
{
string stuName = ""; //提取学生姓名,用于匹配查找
unsigned int posNAME01 = str.find_last_of('=');
unsigned int posNAME02 = str.find_last_of(';');
stuName = str.substr(posNAME01 + , posNAME02 - posNAME01 - ); sort(students.begin(),students.end(),mathCompare);
for(int i = ; i < students.size();++i)
{
if(students[i]->NAME == stuName)
students[i]->mathMarking = i+; //根据数学成绩排序规则,给学生的数学排名赋值
}
sort(students.begin(),students.end(),langCompare);
for(int i = ; i < students.size();++i)
{
if(students[i]->NAME == stuName)
students[i]->langMarking = i+;
}
sort(students.begin(),students.end(),totalCompare);
for(int i = ; i < students.size();++i)
{
if(students[i]->NAME == stuName)
students[i]->totalMarking = i+;
}
for(int i = ; i < students.size();++i)
{
if(students[i]->NAME == stuName) //输出查找学生的信息
cout << students[i]->NAME << " " << students[i]->MATH << " "
<< students[i]->LANG << " " << students[i]->totalScore << " "
<< students[i]->mathMarking << " " << students[i]->langMarking
<< " " <<students[i]->totalMarking;
} } }//while return ;
}
三、
给出两个字符串A,B。将A字符串转化为B字符串,转化共两种方式:删除连续的n个字符,一次操作费用为2。增加连续的n个字符(增加的什么由你决定),一次操作的费用为n+2。求把A变为B最小费用。
输入:第一行输入一个正整数(1<=T<=10),表示有T组测试数据。
对于每组测试数据:
两行字符串A,B(字符串长度不超过2000,字符仅包含小写字母。)
输出:对于每组测试数据,输出一行一个整数,表示最小费用。
样例输入
2
dsafsadfadf
fdfd
aaaaaaaa
bbbbbbbb
样例输出:
7
12
分析:参考知乎(时间复杂度O(N3)),后面自己有时间复杂度O(N2)的方法。
1. 不修改, 只有当str1[j - 1] == str2[i - 1]的情况才可能存在, 此时费用等于将A[0:i-1]变换为B[0:j-1]的最小费用(三种方式中最小的那个),否则为INF
2. 添加结尾, 考虑添加的长度为k,此时费用为将A[0:i]变换成B[0:j-k]再加上一个根据结尾不同变换的COST1
3. 删除结尾, 考虑删除的长度为k,此时费用为将A[0:i-k]变换为B[0:j]再加上一个根据结尾不同变换的COST2
( Insert: Min(F(n,0)+m,...,F(n, m-1)+1)+2;)
作者:AbmiP
链接:https://www.zhihu.com/question/50960106/answer/123577803
来源:知乎
著作权归作者所有,转载请联系作者获得授权。 #define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define INF 3000
using namespace std;
int de[][], ae[][], ne[][];
char s1[], s2[];
int main() {
//freopen("io/in.txt", "r", stdin);freopen("io/out.txt", "w", stdout);
int n, l1, l2;
char c;
scanf("%d%c", &n, &c);
while (n--) {
char* tmp = s1;
char c;
while ((scanf("%c", &c) != EOF) && c != '\n')*(tmp++) = c;
*tmp = '\0';
tmp = s2;
while ((scanf("%c", &c) != EOF) && c != '\n')*(tmp++) = c;
*tmp = '\0';
l1 = strlen(s1);
l2 = strlen(s2);
for (int i = ; i <= l1; i++) {
de[][i] = ; ae[][i] = ne[][i] = INF;
}
for (int i = ; i <= l2; i++) {
ae[i][] = i + ; de[i][] = ne[i][] = INF;
}
ne[][] = ;
for (int j = ; j <= l2; j++)
for (int i = ; i <= l1; i++) {
ne[j][i] = s1[i - ] == s2[j - ] ? min(min(ne[j-][i-], ae[j-][i-]), de[j-][i-]) : INF;
ae[j][i] = de[j][i] = INF;
for (int k = ; k <= j; k++)
ae[j][i] = min(ae[j][i], min(ae[j - k][i] + k, min(de[j - k][i] + k + , ne[j - k][i] + k + )));
for (int k = ; k <= i; k++)
de[j][i] = min(de[j][i], min(de[j][i - k], min(ae[j][i - k] + , ne[j][i - k] + )));
}
printf("%d\n", min(min(ne[l2][l1], ae[l2][l1]), de[l2][l1]));
}
return ;
}
O(N2):
addEnd[i][j]表示通过增加字符,使得str1[0 : j]变换为str2[0 : i];
delEnd[i][j]表示通过删除字符,使得str1[0 : j]变换为str2[0 : i];
noEnd[i][j]表示不做变换,使得str1[0 : j]变换为str2[0 : i]。
#include <iostream>
#include <cstring> using namespace std; #define max 2001
#define INF 10000 int addEnd[max][max];
int delEnd[max][max];
int noEnd[max][max]; int MIN(int x,int y)
{
if(x>y)
return y;
else
return x;
}
void initArray(int addEnd[][max], int delEnd[][max], int noEnd[][max], int len1, int len2)
{
for(int i = ; i <= len1; i++)
{
delEnd[][i] = ;
addEnd[][i] = noEnd[][i] = INF;
}
for(int i = ;i <= len2; i++)
{
addEnd[i][] = i + ;
delEnd[i][] = noEnd[i][] = INF;
}
noEnd[][] = ;
}
void refreshArray(int addEnd[][max],int delEnd[][max],int noEnd[][max],const char* str1,int len1,const char* str2,int len2)
{
for(int i = ;i <= len2; i++)
{
for(int j = ;j <= len1; j++)
{
noEnd[i][j] = (str1[j-]==str2[i-]) ? MIN(addEnd[i-][j-],MIN(delEnd[i-][j-],noEnd[i-][j-])) : INF; delEnd[i][j] = addEnd[i][j] = INF; addEnd[i][j] = MIN(addEnd[i][j], MIN(addEnd[i-][j]+, MIN(delEnd[i-][j]++, noEnd[i-][j]++))); delEnd[i][j] = MIN(delEnd[i][j],MIN(addEnd[i][j-]+,MIN(delEnd[i][j-],noEnd[i][j-]+))); }
}
} int main()
{
int num;
while(cin >> num)
{
int ret[num];
int retID = ;
int retSize = num;
while(num > )
{
char str1[max];
char str2[max]; cin >> str1 >> str2;
int len1 = strlen(str1);
int len2 = strlen(str2); //数组边界预定义
initArray(addEnd, delEnd, noEnd, len1, len2);
//刷新数组
refreshArray(addEnd, delEnd, noEnd, str1, len1, str2, len2);
//保存结果
ret[retID++] = MIN(addEnd[len2][len1],MIN(delEnd[len2][len1],noEnd[len2][len1]));
//此处,切不可使用++retID(先自增为1,并将自增后的值赋给下标);而retID++是自增,并将自增前的值赋给小标。 回忆一下STL中map删除中 it++的用法
--num;
}//end while //result display
for(int i = ; i < retSize; i++)
{
cout << ret[i] << endl;
}
}//end while
return ;
}
HW2016_字符串_STL_DP的更多相关文章
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- JavaScript 字符串实用常操纪要
JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Redis的简单动态字符串实现
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,sds)的抽象类 ...
- ASP.NET加密和解密数据库连接字符串
大家知道,在应用程序中进行数据库操作需要连接字符串,而如果没有连接字符串,我们就无法在应用程序中完成检索数据,创建数据等一系列的数据库操作.当有人想要获取你程序中的数据库信息,他首先看到的可能会是We ...
- Javascript正则对象方法与字符串正则方法总结
正则对象 var reg = new Regexp('abc','gi') var reg = /abc/ig 正则方法 test方法(测试某个字符串是否匹配) var str = 'abc123'; ...
- 微信小程序中利用时间选择器和js无计算实现定时器(将字符串或秒数转换成倒计时)
转载注明出处 改成了一个单独的js文件,并修改代码增加了通用性,点击这里查看 今天写小程序,有一个需求就是用户选择时间,然后我这边就要开始倒计时. 因为小程序的限制,所以直接选用时间选择器作为选择定时 ...
随机推荐
- Transaction (Process ID xxx) was deadlocked on lock
Transaction (Process ID 161) was deadlocked on lock | communication buffer resources with another pr ...
- cell单选
先上图给看看效果 cell单选逻辑就是取出上一个选中的cell 设置图片为默认图片 在取出点击的cell 设置图片为选中图片即可 废话不多说直接上代码 p.p1 { margin: 0.0px 0.0 ...
- JSONArray的应用
从json数组中得到相应java数组,如果要获取java数组中的元素,只需要遍历该数组. /** * 从json数组中得到相应java数组 * JSONArray下的toArray()方法的使用 * ...
- 【Java EE 学习 55】【酒店会员管理系统项目总结】
本酒店会员管理系统使用了SSH框架和传值播客提供的协同OA静态页面. 项目地址:https://github.com/kdyzm/HotelMembersManagement 一.需求分析 酒店会员管 ...
- js获取浏览器body或窗宽度高度合集
<script type="text/javascript"> var s = " "; document.documentElement.scro ...
- UWP Composition API - GroupListView(二)
还是先上效果图: 看完了上一篇UWP Composition API - GroupListView(一)的童鞋会问,这不是跟上一篇一样的吗??? 骗点击的?? No,No,其实相对上一个有更简单粗暴 ...
- java时间计算,获取某月第一天和最后一天
//获取前月的第一天 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); //获取当前月第一天: Calendar ...
- c#程序中对密码进行加密的方法
在ADO.NET中,向数据库添加数据时,怎样对数据中的密码进行加密?(也就是说在数据表中也看不到用户的密 码,只是一些经过编译后的字符串,以防止数据库管理员利用用户的密码进行非法操作.) 首先, ...
- Bug库
netsh int tcp set global ecn=disable C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe ...
- JavaScript(三) 正则表达式 以及实现的功能
RegExp 是正则表达式的缩写.定义RegExp正则表达式 RegExp 对象用于存储检索模式. 通过 new 关键词来定义 RegExp 对象.以下代码定义了名为 p 的 RegExp 对象,其模 ...