一、算法思路是简单的
(1)先求出所有的两数之和,将和与下表存储到mutimap中;
(2)利用 val = { target-(1)两数和 } 去查询multimap ;
(3)如果查到,则记录下对应的序列;如果没有,则不用记录。
二、代码是复杂的
(1)有个四元组的operator< 重载问题,需要复杂的 if/else结构。原来设想的太简单的。
(2)需要multimap、set、vector的综合运用,才能完成复杂的逻辑。
(3)友元的使用还是第一次。
三、代码分为两部分,类以及main测试,如下:
(类):
class node{
//friend bool operator==(const node &l,const node &r);
//friend bool operator!=(const node &l,const node &r);
friend class solution;
friend bool operator< (const node &l,const node &r);
friend ostream& operator<<(ostream& out,const node &four);
public:
node():first(0),second(0),third(0),forth(0){}
node(int a,int b,int c, int d):first(a),second(b),third(c),forth(d){}
public:
int first;
int second;
int third;
int forth;
};
/*bool operator==(const node &l,const node &r){
return (l.first==r.first) && (l.second==r.second)
&& (l.third==r.third) && (l.forth == r.forth);
}
bool operator!=(const node &l,const node &r){
return !(l==r);
}*/
bool operator<(const node &l,const node &r){
//return r.first>l.first?(r.second>l.second?(r.third>l.third?(r.forth>l.forth?1:0):0):0):0;
if(l.first<r.first) return true;
else if(l.first>r.first) return false;
else{
if(l.second<r.second) return true;
else if (l.second>r.second) return false;
else{
if(l.third<r.third) return true;
else if(l.third>r.third) return false;
else{
if(l.forth<r.forth) return true;
else if(l.forth>r.forth) return false;
else return false;
}
}
}
}
ostream& operator<<(ostream& out,const node &four){
out<<four.first<<" "<<four.second<<" "<<four.third<<" "<<four.forth;
return out;
}
class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int> > res;
vector<int> row;
if(num.size()<4) return res;
multimap<int,pair<int,int> > ht;
multimap<int,pair<int,int> >::iterator it,pos;
set<node> s;
int n = num.size();
for(int i =0 ; i< n-1; ++i)
for(int j =i+1 ; j<n;++j){
int tmp = num[i]+num[j];
//ht[tmp]=make_pair(i,j);
ht.insert(make_pair(tmp,make_pair(i,j)));
}
for(it=ht.begin();it!=ht.end();++it){
int k = (*it).first;
int key= target - k;
if(ht.count(key)!=0)
for(pos=ht.lower_bound(key);pos!=ht.upper_bound(key);++pos)
if(
(*it).second.first!= (*pos).second.first &&
(*it).second.second!= (*pos).second.second &&
(*it).second.second!= (*pos).second.first &&
(*it).second.first!= (*pos).second.second
){//cout<<"test ";
//cout<<(*it).second.first<<" "<<(*it).second.second<<" ";
//cout<<(*pos).second.first<<" "<<(*pos).second.second<<endl;
row.clear();
row.push_back(num[(*it).second.first]);
row.push_back(num[(*it).second.second]);
row.push_back(num[(*pos).second.first]);
row.push_back(num[(*pos).second.second]);
sort(row.begin(),row.end());
node x(row[0],row[1],row[2],row[3]);
//cout<<x<<endl;
//x.first=row[0];x.second=row[1];x.third=row[2];x.forth=row[3];
//cout<<s.count(x)<<endl;
if(s.find(x)==s.end()) {s.insert(x);res.push_back(row);}
}
}
return res;
}
};
(测试):
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
using namespace std;
class node{
//friend bool operator==(const node &l,const node &r);
//friend bool operator!=(const node &l,const node &r);
friend bool operator< (const node &l,const node &r);
friend ostream& operator<<(ostream& out,const node &four);
public:
node():first(0),second(0),third(0),forth(0){}
node(int a,int b,int c, int d):first(a),second(b),third(c),forth(d){}
public:
int first;
int second;
int third;
int forth;
};
/*bool operator==(const node &l,const node &r){
return (l.first==r.first) && (l.second==r.second)
&& (l.third==r.third) && (l.forth == r.forth);
}
bool operator!=(const node &l,const node &r){
return !(l==r);
}*/
bool operator<(const node &l,const node &r){
//return r.first>l.first?(r.second>l.second?(r.third>l.third?(r.forth>l.forth?1:0):0):0):0;
if(l.first<r.first) return true;
else if(l.first>r.first) return false;
else{
if(l.second<r.second) return true;
else if (l.second>r.second) return false;
else{
if(l.third<r.third) return true;
else if(l.third>r.third) return false;
else{
if(l.forth<r.forth) return true;
else if(l.forth>r.forth) return false;
else return false;
}
}
}
}
ostream& operator<<(ostream& out,const node &four){
out<<four.first<<" "<<four.second<<" "<<four.third<<" "<<four.forth;
return out;
}
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int> > res;
vector<int> row;
if(num.size()<4) return res;
multimap<int,pair<int,int> > ht;
multimap<int,pair<int,int> >::iterator it,pos;
set<node> s;
int n = num.size();
for(int i =0 ; i< n-1; ++i)
for(int j =i+1 ; j<n;++j){
int tmp = num[i]+num[j];
//ht[tmp]=make_pair(i,j);
ht.insert(make_pair(tmp,make_pair(i,j)));
}
for(it=ht.begin();it!=ht.end();++it){
int k = (*it).first;
int key= target - k;
if(ht.count(key)!=0)
for(pos=ht.lower_bound(key);pos!=ht.upper_bound(key);++pos)
if(
(*it).second.first!= (*pos).second.first &&
(*it).second.second!= (*pos).second.second &&
(*it).second.second!= (*pos).second.first &&
(*it).second.first!= (*pos).second.second
){//cout<<"test ";
//cout<<(*it).second.first<<" "<<(*it).second.second<<" ";
//cout<<(*pos).second.first<<" "<<(*pos).second.second<<endl;
row.clear();
row.push_back(num[(*it).second.first]);
row.push_back(num[(*it).second.second]);
row.push_back(num[(*pos).second.first]);
row.push_back(num[(*pos).second.second]);
sort(row.begin(),row.end());
node x(row[0],row[1],row[2],row[3]);
//cout<<x<<endl;
//x.first=row[0];x.second=row[1];x.third=row[2];x.forth=row[3];
//cout<<s.count(x)<<endl;
if(s.find(x)==s.end()) {s.insert(x);res.push_back(row);}
}
}
return res;
}
int main() {
// your code goes here
vector<int> num;int n;int target;int tmp;
cin>>n>>target;
for(int i=0 ; i<n; i++){
cin>>tmp;num.push_back(tmp);
}
vector<vector<int> > res;
res = fourSum(num,target);
if(res.size()==0){cout<<"empty result "<<endl; return 0;}
int row = res.size();
//if(!row) return 0;
int col = res[0].size();
//if(!col) return 0;
for(int i=0 ; i< row; i++){
for(int j =0 ; j< col; j++)
cout<<res[i][j]<<" ";
cout<<endl;
}
return 0;
}