Mercurial > algorithms
changeset 4:b06f215a4c69
Added two variants of two_sum.cpp
author | Eris Caffee <discordia@eldalin.com> |
---|---|
date | Mon, 04 May 2015 12:32:58 -0500 |
parents | 5b53a317106c |
children | d48b3fb142f0 |
files | two_sum/two_sum.cpp two_sum/two_sum_hash.cpp two_sum/two_sum_sort.cpp |
diffstat | 3 files changed, 134 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- a/two_sum/two_sum.cpp Fri May 01 16:28:22 2015 -0500 1.2 +++ b/two_sum/two_sum.cpp Mon May 04 12:32:58 2015 -0500 1.3 @@ -15,6 +15,10 @@ 1.4 // into the hash, which adds only a small constant to the running time per 1.5 // iteration of the loop.) 1.6 1.7 +// NOTE: Compare this to two_sum_hash.cpp, which implements the same algorithm 1.8 +// for arbitrary input arrays and prints all matching pairs instead of just the 1.9 +// first. 1.10 + 1.11 // Usage: Pass the target value as a command line option, and the number array as 1.12 // values on stdin, one item per line. 1.13
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/two_sum/two_sum_hash.cpp Mon May 04 12:32:58 2015 -0500 2.3 @@ -0,0 +1,65 @@ 2.4 +// Problem: given an input array of numbers, and a target value, find all pairs 2.5 +// of numbers in the input which sum to the target value. 2.6 + 2.7 +// Solution: Add the input numbers to a hash with the number as the hash key, 2.8 +// and it's index position in the input as the hash value. 2.9 + 2.10 +// At each step we can do an O(1) lookup in the hash to see if target - num has 2.11 +// already been added to the hash. If it has, we terminate processing and print 2.12 +// the two numbers (along with their indices). Otherwise we add num to the hash 2.13 +// and loop back to read the next input number. 2.14 + 2.15 +// Overall performance is O(N) in the worst case, since in that case we must 2.16 +// process each input item exactly once. (For each item, we perform one lookup 2.17 +// into the hash, which adds only a small constant to the running time per 2.18 +// iteration of the loop.) 2.19 + 2.20 +// Usage: Pass the target value as a command line option, and the number array as 2.21 +// values on stdin, one item per line. 2.22 + 2.23 +#include <map> 2.24 +#include <string> 2.25 +#include <cstdlib> 2.26 +#include <iostream> 2.27 +#include <vector> 2.28 + 2.29 +void two_sum( std::vector<long> vec, long target ) { 2.30 + std::map<long, long> hash; 2.31 + 2.32 + for ( long i=0; i < vec.size(); i++ ) { 2.33 + hash[vec[i]] = i; 2.34 + } 2.35 + 2.36 + long lookfor; 2.37 + long i = 0; 2.38 + std::map<long, long>::iterator it; 2.39 + while ( i < vec.size() ) { 2.40 + if ( vec[i] <= target/2 ) { 2.41 + lookfor = target - vec[i]; 2.42 + if ( ( ( it = hash.find(lookfor) ) != hash.end() ) && ( (*it).first != vec[i] ) ) { 2.43 + std::cout << vec[i] << " " << lookfor << " (indices " << i << ", " << (*it).second << ")" << std::endl; 2.44 + } 2.45 + } 2.46 + i++; 2.47 + } 2.48 + } 2.49 + 2.50 +int main( int argc, char **argv ) { 2.51 + char *endptr = NULL; 2.52 + long target = strtol( argv[1], &endptr, 10); 2.53 + 2.54 + std::vector<long> vec; 2.55 + long num; 2.56 + std::string s; 2.57 + 2.58 + while ( std::cin >> s ) { 2.59 + num = strtol( s.c_str(), &endptr, 10); 2.60 + vec.push_back(num); 2.61 + } 2.62 + 2.63 + two_sum( vec, target ); 2.64 + 2.65 + exit(EXIT_SUCCESS); 2.66 + } 2.67 + 2.68 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/two_sum/two_sum_sort.cpp Mon May 04 12:32:58 2015 -0500 3.3 @@ -0,0 +1,65 @@ 3.4 +// Problem: given an input array of numbers, and a target value, find all pairs 3.5 +// of numbers in the input which sum to the target value. 3.6 + 3.7 +// Solution: Sort the input data. We can now use binary search to look up target numbers. 3.8 + 3.9 +// Time performance is O(N log N) for the lookup, and varies for the sort, 3.10 +// though here it is also O(N log N) giving O(N log N) overall performance. 3.11 +// Space complexity if O(1), though, since no extra space is needed for the operations. 3.12 + 3.13 +// Usage: Pass the target value as a command line option, and the number array as 3.14 +// values on stdin, one item per line. 3.15 + 3.16 +#include <algorithm> 3.17 +#include <vector> 3.18 +#include <string> 3.19 +#include <cstdlib> 3.20 +#include <iostream> 3.21 + 3.22 +long binary_search( std::vector<long> vec, long lookfor, long min, long max ) { 3.23 + while ( max >= min ) { 3.24 + long mid = min + (max - min) / 2; 3.25 + if ( vec[mid] == lookfor ) 3.26 + return mid; 3.27 + else if ( vec[mid] > lookfor ) 3.28 + max = mid - 1; 3.29 + else 3.30 + min = mid + 1; 3.31 + } 3.32 + return -1; 3.33 + } 3.34 + 3.35 +void two_sum( std::vector<long> vec, long target ) { 3.36 + std::sort( vec.begin(), vec.end() ); 3.37 + 3.38 + long lookfor; 3.39 + long i = 0; 3.40 + while ( vec[i] <= target/2 ) { 3.41 + lookfor = target - vec[i]; 3.42 + long pos = binary_search( vec, lookfor, 0, vec.size()-1 ); 3.43 + if ( pos != -1 && pos != i ) { 3.44 + std::cout << vec[i] << " " << lookfor << " (indices " << i << ", " << pos << ")" << std::endl; 3.45 + } 3.46 + i++; 3.47 + } 3.48 + } 3.49 + 3.50 +int main( int argc, char **argv ) { 3.51 + char *endptr = NULL; 3.52 + long target = strtol( argv[1], &endptr, 10); 3.53 + 3.54 + std::vector<long> vec; 3.55 + long num; 3.56 + std::string s; 3.57 + 3.58 + while ( std::cin >> s ) { 3.59 + num = strtol( s.c_str(), &endptr, 10); 3.60 + vec.push_back(num); 3.61 + } 3.62 + 3.63 + two_sum( vec, target ); 3.64 + 3.65 + exit(EXIT_SUCCESS); 3.66 + } 3.67 + 3.68 +