带有重复元素数组的解压缩

生来就可爱ヽ(ⅴ<●) 提交于 2020-03-09 15:57:29

在这里插入图片描述题目来源是隔壁班级老师c++实验课的题目,看着蛮变态的,比笔者班级的实验题难的不是一点半点,那么具体怎么实现呢

核心的思路来源与以前写过的连续几个连续输入的整型数,每种数字一共连续出现过几次,看看它的代码长什么样

int currval=0,val=0;
    if(std::cin>>currval)
    {
        int cnt=1;
        while(std::cin>>val)
        {
            if(val==currval)
            ++cnt;
            else
            {
                std::cout<<currval<<" occurs "<<cnt<<" times"<<std::endl;
                currval=val;
                cnt=1;
            }
        }
        std::cout<<currval<<" occurs "<<cnt<<" times"<<std::endl;
    }

这个代码很简单,我就没加注释了,那么解压缩数组的题目要求和这道题有极其相似的地方,都是连续的数字,都要输出连续出现了几次,只不过要求把单独出现的数字特殊化处理以及提供解压的函数,实际上本质是没有太大改变的。那么怎么对单独出现的数字特殊化处理呢,笔者采用的方法是:遇到单独出现的数字,在压缩结果的这个数组中(以下简称result),相应的位置用-1代替,然后把这个数字存到另外一个单独存放这种单一数字的数组中去(以下简称single_result),可能文字描述有些难以理解,那么看看按照这种方式压缩后两个数组分别长什么样吧
在这里插入图片描述如图,第一行和第二行是原始的数组,即a[100],result是主要的压缩后的数据,single_result是存放单个数字的压缩后数据

a[100]的前三个是连续的3个1,那么result相应的结果就是“3,1”,然后是3个3,result相应的结果就是“3,3”,然后是“4,5,6”,这3个单独的数字,那么在result中用-1代替,就是“-1,-1,-1”,然后把他们存在single_result中。

这就是压缩的原理,那么看看代码是怎么实现的

void compress(int a[100],vector<int> &result,vector<int> &single_result){
    int currval=0,val=0;
    if(currval=a[0]){
        int cnt=1;
        for(int i=1;i<100;i++){
            val=a[i];
            if(val==currval)
                ++cnt;//如果和上次的数据一样,计数值加一
            else{//如果不一样,将压缩后的数据放入result或single_result中
                if(cnt!=1){//计数值不为1,将计数值和数字压入result的末尾
                    result.push_back(cnt);
                    result.push_back(currval);
                }
                else{//计数值为1,将将-1压入result末尾,将数字压入single_result
                    result.push_back(-1);
                    single_result.push_back(currval);
                }
                currval=val;
                cnt=1;
            }
        }
        if(cnt!=1){//同上
            result.push_back(cnt);
            result.push_back(currval);
        }
        else{//同上
            result.push_back(-1);
            single_result.push_back(currval);
        }
    }
}

复制代码

大体的结构和原来一样,只是加了相关的vector操作

那么解压的函数如何实现呢,实际上了有了压缩后的结构,解压就很简单了,直接贴代码,具体原理应该都看得懂

void decompress(vector<int> &result,vector<int> &single_result){
    vector<int> final;
    for(int i=0,j=0;i<result.size();){
        if(result[i]!=-1){
            for(int k=0;k<result[i];k++){
                final.push_back(result[i+1]);
            }
            i+=2;
        }
        else{
            final.push_back(single_result[j]);
            j++;
            i++;
        }
    }
    for(auto a:final){
        cout<<a<<",";
    }
    cout<<endl;
}

贴个结果看看正确性
在这里插入图片描述按理说还有改进的方法,笔者能想到的就是把连续 几个单独的数字用一个-1来表示,但是相应的会在single_result中增加一个参数表示连续的单数字出现的数量,本质上压缩大小并未减少,因此未进行代码实现。

以上案例代码没有加上指针,以下是使用指针的完整代码

#include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 void compress(int *p,vector<int> *result,vector<int> *single_result){
 5     int currval=0,val=0;
 6     if(currval=*p){
 7         int cnt=1;
 8         for(int i=1;i<100;i++){
 9             val=*(p+i);
10             if(val==currval)
11                 ++cnt;
12             else{
13                 if(cnt!=1){
14                     result->push_back(cnt);
15                     result->push_back(currval);
16                 }
17                 else{
18                     result->push_back(-1);
19                     single_result->push_back(currval);
20                 }
21                 currval=val;
22                 cnt=1;
23             }
24         }
25         if(cnt!=1){
26             result->push_back(cnt);
27             result->push_back(currval);
28         }
29         else{
30             result->push_back(-1);
31             single_result->push_back(currval);
32         }
33     }
34 }
35 void decompress(vector<int> *result,vector<int> *single_result){
36     vector<int> final;
37     for(int i=0,j=0;i<result->size();){
38         if((*result)[i]!=-1){
39             for(int k=0;k<(*result)[i];k++){
40                 final.push_back((*result)[i+1]);
41             }
42             i+=2;
43         }
44         else{
45             final.push_back((*single_result)[j]);
46             j++;
47             i++;
48         }
49     }
50     for(auto a:final){
51         cout<<a<<",";
52     }
53     cout<<endl;
54 }
55 int main(){
56     int a[100]={1,1,1,3,3,3,4,5,6,5,5,5,5,5,3,3,4,4,7,8,9,1,1,1,3,3,3,3,4,4,5,4,6,5,5,5,5,4,4,4,5,3,3,3,3,4,4,4,4,7,7,7,7,8,9,9,9,9,0,0,0,0,3,3,3,4,5,6,7,3,3,3,5,5,5,8,7,8,8,8,8,3,3,3,4,4,5,5,5,5,4,5,5,4,4,4,4,1,1,1};
57     vector<int> *result=new vector<int>;
58     vector<int> *single_result=new vector<int>;
59     compress(a,result,single_result);
60     cout<<"After compress:";
61     for(auto a:*result) cout<<a<<",";
62     cout<<endl;
63     for(auto a:*single_result) cout<<a<<",";
64     cout<<endl;
65     cout<<"Decompress:";
66     decompress(result,single_result);
67     delete result;
68     delete single_result;
69     system("pause");
70     return 0;
71 }

ps:隔壁学到这里的时候是没有学到vector的,所以实际上我写的有点超纲了,但是数组配指针的组合真的难看,懒得写了(小声逼逼)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!