1 能否快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值
2
3 /*************************************************
4 设计者:cslave
5 版本说明:本代码免费用于商用,拷贝,转移,使用,但是
6 有本代码导致的问题,本人概不负责。
7 设计时间:2012.6.25
8 分发原则:遵守GNU规范。
9 **************************************************/
10
11 // 快速寻找满足条件的两个数.cpp : 定义控制台应用程序的入口点。
12 //
13
14 #include "stdafx.h"
15 #include <stdlib.h>
16 #include <iostream>
17 using namespace std;
18
19 //查找数组中是否存在任意个数字,使其和等于给定值
20
21 struct Point //查找两个数和等于定值时用以返回两数下标值的结构
22 {
23 int Begin;
24 int End;
25 };
26
27 Point point={0,0};
28 int compare(const void* a,const void* b) //比较函数,qsort使用
29 {
30 return (*(int*)a-*(int*)b);
31 }
32
33
34 bool IsSeriesExistSum(int* Arr,int ExpectSum,int Length) //判断是否存在一系列数使其和等于定值
35 {
36 if(!Arr||Length<=0)
37 return false;
38 int Sum=0;
39 qsort(Arr,Length,sizeof(int),compare);
40 for(int i=0;i<Length;i++)
41 {
42 cout<<Arr[i]<<" ";
43 Sum+=Arr[i];
44 }
45 cout<<endl;
46 if(Sum==ExpectSum)
47 {
48 cout<<"起点:"<<0<<"终点:"<<Length-1<<endl;
49 return true;
50 }
51 for(int i=0,j=Length-1;i<j;)
52 {
53 if(Sum==ExpectSum)
54 {
55 cout<<"起点:"<<i<<"终点:"<<j<<endl;
56 return true;
57 }
58 else if(Sum<ExpectSum) //如果小于给定值 ,i++ 考虑了负数元素情形,所以这里没有擅自对Sum判断
59 {
60 Sum-=Arr[i];
61 i++;
62 }
63 else
64 {
65 Sum-=Arr[j];
66 j--;
67 }
68 }
69 return false;
70 }
71
72 bool IsTwoExistSum(int* Arr,int ExpectSum,int Length)//判断是否存在两数之和为定值
73 {
74 if(!Arr||Length<=0)
75 return false;
76 qsort(Arr,Length,sizeof(int),compare);
77 for(int i=0;i<Length;i++)
78 {
79 cout<<Arr[i]<<" ";
80 }
81 cout<<endl;
82 for(int i=0,j=Length-1;i<j;)
83 {
84 if(Arr[i]+Arr[j]==ExpectSum)
85 {
86 cout<<"元素1位置:"<<i<<"元素2位置:"<<j<<endl;
87 return true;
88 }
89 else if(Arr[i]+Arr[j]<ExpectSum)
90 {
91 i++;
92 }
93 else
94 {
95 j--;
96 }
97 }
98 return false;
99 }
100
101 int IsNearlyExistSum(int* Arr,int ExpectSum,int Length)//判断两数之和与定值的最近值,
102 {
103 if(!Arr||Length<=0)
104 return false;
105 int Epsino=0x7FFFFFFF; //初始时赋值为最大
106 qsort(Arr,Length,sizeof(int),compare);
107 for(int i=0;i<Length;i++)
108 {
109 cout<<Arr[i]<<" ";
110 }
111 cout<<endl;
112 int Begin,End;
113 for(int i=0,j=Length-1;i<j;)
114 {
115 if(abs(Arr[i]+Arr[j]-ExpectSum)<Epsino) //如果存在更接近定值,则更新
116 {
117 Begin=i;End=j;
118 Epsino=abs(Arr[i]+Arr[j]-ExpectSum);
119 }
120 if(Arr[i]+Arr[j]<ExpectSum)
121 {
122 i++;
123 }
124 else
125 {
126 j--;
127 }
128 }
129 point.Begin=Begin;
130 point.End=End;
131 return Arr[Begin]-Arr[End];
132 }
133
134 void Test1()
135 {
136 int Arr[6]={-2,-1,0,14,7,9};
137 if( IsSeriesExistSum( Arr,15,6))
138 cout<<"ExpectSum have Found!"<<endl;
139 }
140 void Test2()
141 {
142 int Arr[6]={-2,-1,0,14,7,9};
143 if( IsTwoExistSum( Arr,8,6))
144 cout<<"ExpectSum have Found!"<<endl;
145 }
146
147 void Test3()
148 {
149 int Arr[6]={-2,-1,0,14,7,9};
150 int Epsino=IsNearlyExistSum( Arr,11,6);
151 cout<<"ExpectSum have Found!"<<Epsino<<endl;
152 cout<<"元素1位置:"<<point.Begin<<"元素2位置:"<<point.End<<endl;
153 }
154
155 int _tmain(int argc, _TCHAR* argv[])
156 {
157 Test1();
158 Test2();
159 Test3();
160 return 0;
161 }