合并表记录

描述

数据表记录包含表索引和数值(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。
示例
输入:
4
0 1
0 2
1 2
3 4
输出:
0 3
1 2
3 4

方法一

思路分析

本题方法一使用暴力求解,即:先将所有的索引和数值全部存储起来,然后两层循环找到重复的索引数值合并,并对重复的结点进行标记,最后顺序输出所有的索引数值。具体实现如下:
  • 设置一个结构体,含有索引和数值,此外还设置了一个标记,用于表示是否重复;
  • 然后循环将重复的索引的数值求和,并标记重复索引数值对(除第一个)
  • 根据index对所有的索引数值进行排序
  • 最后顺序输出非重复的索引数值

图解

$index$ 0 0 1 3 1
$value$ 1 2 2 4 1
$index_i$ 1 1 1 1 1

(1)两重循环合并重复的索引数值对,并将重复的索引数值标记,如下:
$index$ 0 0 1 3 1
$value$ 3 2 3 4 1
$index_i$ 1 -1 1 1 -1

(2)随后按照$index$进行排序,得到:
index 0 0 1 1 3
value 3 2 3 1 4
$index_i$ 1 -1 1 -1 1

(3)输出$index_i=1$的索引数值对。

核心代码

#include<bits/stdc++.h>
using namespace std;
struct table
{
    int index;
    int value;
    int index_i=1;//标记这组数是否重复,1表示不重复
};
bool Cmpare(const table &a, const table &b)
{
     return a.index < b.index;//按照index排序
}
int main()
{
    int n;
    cin>>n;
    vector<table>temp(n);
    for(int i=0;i<n;i++)
    {
        int m,p;
        cin>>m>>p;
        temp[i].index=m;
        temp[i].value=p;
    }
     for(int i=0;i<n;i++)
    {
       for(int j=i+1;j<n;j++)
       {
           if(temp[j].index_i!=-1&&temp[i].index==temp[j].index)//将重复的结点合并,并标记
           {
               temp[i].value+=temp[j].value;
               temp[j].index_i=-1;
           }
       }
    }
    sort(temp.begin(),temp.end(),Cmpare);//按照index排序
    for(int i=0;i<n;i++)
    {
        if(temp[i].index_i==1)//输出不重复的结点
           cout<<temp[i].index<<" "<<temp[i].value<<endl;
    }
    
    return 0;
}
复杂度分析
  • 时间复杂度:二重循环对所有的重复索引数值合并,时间复杂度为$O(n^2)$,按照索引值对索引数值排序,时间复杂度为$O(nlogn)$,因此总的时间复杂度为$O(n^2)$
  • 空间复杂度:设置结构体数组存储所有的索引数值,在结构体中有必要的int值存储索引数值,还设置了一个标记整数,因此需要额外的内存空间,因此空间复杂度为$O(n)$


方法二

思路分析

直接使用C++中STL中的map结构。C++ 中 map 提供的是一种键值对容器,里面的数据都是成对出现的,每一对中的第一个值称之为关键字(key),每个关键字只能在 map 中出现一次;第二个称之为该关键字的对应值。

核心代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    map<int,int> mp;//初始化map,value=0
    for(int i=0;i<n;i++)
    {
        int p=0,q=0;
        cin>>p>>q;
        mp[p]+=q;//合并重复的点
    }
    for(auto it = mp.begin();it!=mp.end();++it)
        cout<<it->first<<" "<<it->second<<endl;
    
}
复杂度分析
  • 时间复杂度:时间复杂度为$O(n)$
  • 空间复杂度:设置一个map容器,用于存储表索引和数值,没有使用额外的内存空间,空间复杂度为$O(1)$