题目及要求
问题描述 :
目的:使用自行设计的顺序表ADT或STL的vector模板设计并实现顺序表应用场合的一些简单算法设计。
应用7:试设计一个算法,找出有序顺序表A(顺序表A中的数据元素的数据类型为int型,非空表,且无重复值)中两个元素和为给定值sum的所有元素对,并保持原顺序表不变。
(1)顺序表ADT版本
参考函数原型:
template<class ElemType>
void Search_Pairs( const SqList<ElemType> &A, int sum );
(2)vector版本
参考函数原型:
template<class ElemType>
void Search_Pairs( const vector<ElemType> &A, int sum );
输入说明 :
第一行:有序顺序表A的数据元素(数据元素之间以空格分隔)
第二行:给定值sum
输出说明 :
第一行:顺序表A的遍历结果数据元素之间以“,”分隔)
第二行开始:符合条件的元素对(输出格式见测试数据范例)
如无符合条件的元素对,输出"NULL"
输入范例 :
-3 -2 -1 4 5 6
3
输出范例 :
-3,-2,-1,4,5,6
(-3,6),(-2,5),(-1,4)
分析
/*
* 首先面对这道题,我觉得重点在下面两点上
* 1.利用有序序列这一点,应该知道第一个数往后走,第二个数应该往前走,才能满足新的一对数之和
* 仍然是定值sum
* 2.要考虑有序序列中数字重复的现象,不要重复输出同一对
*/
然后,由于老师要求,我使用的是类模板实现,听说用vector更加简单。我个人还是喜欢编译头文件的,下面是我头文件里的代码
//
// Created by 86177 on 2023/3/27.
//
#ifndef UNTITLED1_SQLIST_H
#define UNTITLED1_SQLIST_H
#endif //UNTITLED1_SQLIST_H
#define Status int
#define OK 1
#define ERROR 0
#define MAXSIZE 100
#define OVERFLOW -2
#include "iostream"
#include "stdlib.h"
#include "cstring"
#include<bits/stdc++.h>
using namespace std;
template <class elemtype>
class adt
{
private:
elemtype *elem;
int length;
public:
adt();
adt(int n);
~adt();
void coutList();
void coutList(int sum);
int getlength();
Status judge(int sum,int i,int j);
};
template <class elemtype>
adt<elemtype>::~adt()
{
}
template <class elemtype>
Status adt<elemtype>::judge(int sum,int i,int j)
{
i++;
while(i<j)
{
if(elem[i]+elem[j]==sum)return OK;
else if(elem[i]+elem[j]<sum)i++;
else if(elem[i]+elem[j]>sum)j--;
}
return ERROR;//表示这个区间没有满足条件的元素对了
}
template <class elemtype>
adt<elemtype>::adt(){//创建一个线性表并且初始化,是无限数目元素的初始化,数组元素最多个数取决于MAXSIZE
elem=new elemtype[MAXSIZE];
int i=0,n=0;
string str;
getline(cin,str);//先让他输入str字符串,包括回车,同时输到会车时就会停止
stringstream ss(str);
while(ss>>elem[i++])n++;//这里当ss输到回车,他就自动循环结束
length=n;
if(length>MAXSIZE)cout<<ERROR;
}
template <class elemtype>
int adt<elemtype>:: getlength()//得到线性表的长度
{
return length;
}
template <class elemtype>
void adt<elemtype>::coutList()//按照题目要求的输出格式输出有序表
{
int i;
for(i=0;i<getlength()-1;i++)
{
cout<<elem[i]<<",";
}
cout<<elem[i]<<endl;
}
template <class elemtype>
void adt<elemtype>::coutList(int sum)//按格式输出所有满足条件的元素对
{
int i,j;
i=0;
j= getlength()-1;
int cot=0;
while(i<j)
{
if(elem[i]+elem[j]==sum)
{//执行输出操作
printf("(%d,%d)",elem[i],elem[j]);
cot++;
while(elem[i]==elem[i+1]){
i++;//判断重复元素
}
if(judge(sum,i,j))cout<<",";
i++;
}
else if(elem[i]+elem[j]<sum)
{
i++;
}
else if(elem[i]+elem[j]>sum)
{
j--;
}
}
if(cot==0)cout<<"NULL";
}
由于我有边编写代码,边写注释捋清思路的习惯,代码中注释较多,我也不再多说。
编写时遇到了一些问题
/*
* 1第一个错误以及发现
* 这些代码之前出现过一次问题怎么都不知道哪里错了,后来问了bwl才
* 发现
* #define elemtype int这行语句与template<class elemtype>好像是不能同时存在的
* 会有编译错误,尽管现在还没有特别明白,但是好歹记住了
* 2.第二个错误以及发现
* 然后我弄好了以后它显示10个warning15个typos但是没有error可是我一点编译
* 他就给我显示在第几微秒的时候编译错误,还不显示哪一行编译错误,只给我弹出了一大堆
* 我看不懂的英文,后来问了zlc以后才发现,哪里有问题人家都给你说了,只不过你看不懂而已哈哈哈
* 发现
* 只有你定义的所有函数全部编写了才能编译成功,我当时没有把析构函数的函数体写了,实际上
* 定义完了以后还要编写一个空函数给析构函数,才行
* 总结
* 每一个定义了的函数,都要写出函数体,哪怕是空的函数体,也要写
*/