微软2014编程之美挑战赛初赛第二场 题目2 : 字符串压缩

虽然很努力的做,但是最后还是没有赶在截止时间之前提交。不知道那些2个小时做3道题的是怎么办到的。。。。

深深认识到自己的菜,2个小时还没做出一道题。练得太少了!

虽然解出来了,但是没有考虑大数据的问题。对于小数据的测试结果正确。


解题思路:

根据每一个输入的字符串,分别构造vector<vector<char>>字符表。然后对字符表排序。

先根据第一列排序,排序后然后对于第一列字符相同的行根据第二列的值进行排序。

如果第一列,第二列的值相同的行有多行,那么对于这几行,再根据第三列的值进行排序。依次类推。

对于两个排好序的字符表,比较它们是否完全相同,如果相同,则两个压缩字符串对应于相同的文件内容。

思路比较简单,但是完全没有用到什么巧妙的算法,设计。感觉有点蠢。




题目:

=================================================================

题目2 : 字符串压缩

时间限制: 8000ms
单点时限: 4000ms
内存限制: 256MB

描述

你的硬盘上有一个神秘的文件占用了大量空间,你决定将其压缩以节省空间。不幸的是,你还没有安装任何压缩软件,所以你决定自己编写一个压缩程序。你发现这是一个文本文件,包括很多行。每行是一个长度恰好为L的字符串,而且字符串可能有重复。行的顺序并不重要,换言之,打乱顺序之后仍然可以认为文件内容和原来相同。

例如,这个文件的内容可以是这样的:

bar

car

bat

cat

cat


经过一段时间观察,你发现同一列的字符往往是相同的,于是你设计了一个简单的压缩框架。首先以某种策略调整行的顺序,然后把所有字符串按照先列后行的顺序变换成单个字符串,例如上面的例子,不调整顺序则直接变换成:

bcbccaaaaarrttt

然后使用游程编码(RLE)的到压缩变换后的字符串:

1b1c1b2c5a2r3t

当然也可以先调换顺序:

car

cat

cat

bat

bar

这样的压缩字符串为:

3c2b5a1r3t1r

比不调整顺序的稍短一些。

现在,你已经得到了两个不同的压缩字符串,你想知道他们解压后的文件是否相同,请写一个程序解决这个问题。


输入

第一行是一个整数T (T <= 30),表示测试数据组数。

每组测试数据占三行。第一行为整数L,表示原始文件中每一行字符串的长度。第二行和第三行分别是两个压缩字符串,格式如c1 n1 c2 n2 … cMnM,表示字符ci连续出现了ni次。具体格式见样例。输入字符串只含a到z的小写字母,确保压缩字符串合法有效,且不为空。


输出

对每组测试数据,首先输出”Case x: ”,其中x表示测试数据编号。如果两个压缩字符串对应于相同的文件内容,则输出”Yes”,否则输出”No”。


数据范围

小数据:1<=L<=10, 1<=ni<=100,压缩字符串长度不超过10^4

大数据:1<=L<=1000, 1<=ni<=10^9,压缩字符串长度不超过10^6



样例输入
2
3
1b1c1b2c5a2r3t
3c2b5a1r3t1r
2
20a20b10a20b10a
20a20b20a20b
样例输出
Case 1: Yes
Case 2: No



vs2012  代码:

====================================================================

#include <iostream>
#include <string>
#include <vector>

using namespace std;

//对vector中的从begin到end的列根据sortIndex列的值进行排序。
void sort(vector<vector<char>> & vec,int begin,int end,int sortIndex){

if(begin<end){

for(int i=begin;i<=end;i++){

int j=i,minIndex;
vector<char> minLine;
minLine=vec[i];
minIndex=i;
while(j<=end){
if(minLine[sortIndex]>vec[j][sortIndex]){
minLine=vec[j];
minIndex = j;  
}
j++;
}
vector<char> exchangeTempLine;
exchangeTempLine = vec[i];
vec[i] = minLine;
vec[minIndex] = exchangeTempLine;
}


}
}


//比较sortIndex(不含)前面的部分是否相同。begin到end。
bool frontEqual(vector<vector<char>> & vec,int begin,int end,int sortIndex){

for(int i=0;i<sortIndex;i++){

if(vec[begin][i]!=vec[end][i]) return false;

}
return true;
}


//对vector排序。
void sortVec(vector<vector<char>> & toatalChart,int sizeEachLine){

for(int i=0;i<sizeEachLine;i++){

int begin = 0;//,end;
for(int j=1;j<toatalChart.size();j++){

if(frontEqual(toatalChart,begin,j,i)){
//end = j;
}else{
sort(toatalChart,begin,j-1,i);
begin = j;
}
}

sort(toatalChart,begin,toatalChart.size()-1,i);
}

}


//比较两个vector是否相等。
bool vectorEqual(vector<vector<char>> & vec1,vector<vector<char>> & vec2){


if(vec1.size()!=vec2.size()) return false;

for(int i=0;i<vec1.size();i++){

if(vec1[i].size()!=vec2[i].size()) return false;

for(int j=0;j<vec1[0].size();j++){
if(vec1[i][j]!=vec2[i][j]) return false;
}
}

return true;

}


void makeVector(string str,int sizeEachLine,vector<vector<char>> & toatalChart){

int strlength = str.length();
int totalCharNum = 0;
int totalLineNum;

int tempNum=0;
for(int i=0;i<strlength;i++){
 
if(str[i]>='0'&&str[i]<='9'){
tempNum=tempNum*10+(str[i]-48);
}else{
totalCharNum += tempNum;
tempNum = 0;
}
}

totalLineNum = totalCharNum/sizeEachLine;

//构造vector。
for(int i=0;i<totalLineNum;i++){
vector<char> char_vec;
for(int j=0;j<sizeEachLine;j++){
 
char_vec.push_back(' ');
}
toatalChart.push_back(char_vec);
}

char insertChar;
int charNum = 0;
int insertBegin = 0;
for(int i=0;i<strlength;i++){
 
if(str[i]>='0'&&str[i]<='9'){
charNum=charNum*10+(str[i]-48);
}else{
insertChar = str[i];
 
for(int i=0;i<charNum;i++){
int a,b;
a = (insertBegin+i)%totalLineNum;
b = (insertBegin+i)/totalLineNum;
toatalChart[a][b] = insertChar;
}

insertBegin += charNum;
charNum = 0;
}
}


}




int main(void) {

string outputStr;
vector<string> output_str;

int totalCaseNum;
cin>>totalCaseNum;

vector<vector<char>> toatalChart1;
vector<vector<char>> toatalChart2;

int sizeEachLine,totalLineNum;
string str;

for(int caseNum=1;caseNum<=totalCaseNum;caseNum++){

cin>>sizeEachLine;

vector<vector<char>> toatalChart1;
vector<vector<char>> toatalChart2;

cin>>str;
//getline(cin, str);
//getline(cin, str);
makeVector(str,sizeEachLine,toatalChart1);
//getline(cin, str);
cin>>str;
makeVector(str,sizeEachLine,toatalChart2);

sortVec(toatalChart1,sizeEachLine);
sortVec(toatalChart2,sizeEachLine);

if(vectorEqual(toatalChart1,toatalChart2)){


      char temp[10];
                   sprintf(temp, "%d", caseNum);
  string tempStr(temp);
  outputStr = "Case " + tempStr + ": Yes";
  output_str.push_back(outputStr);
}else{
  char temp[10];
  sprintf(temp, "%d", caseNum);
  string tempStr(temp);
  outputStr = "Case " + tempStr + ": No";
  output_str.push_back(outputStr);
}
}


for(int i=0;i<output_str.size();i++){

cout<<output_str[i]<<endl;
}


    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值