From b652cffba4f54dcb05f9ca18ac6bb73cf046b8b5 Mon Sep 17 00:00:00 2001 From: En Yi Date: Mon, 26 Aug 2019 17:53:06 +0800 Subject: [PATCH] Add splitted sorted array search --- split_array.cc | 140 +++++++++++++++++++++++++++++++++++ split_array_visual.cc | 167 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 split_array.cc create mode 100644 split_array_visual.cc diff --git a/split_array.cc b/split_array.cc new file mode 100644 index 0000000..cbce522 --- /dev/null +++ b/split_array.cc @@ -0,0 +1,140 @@ +/**This is the code for search an index in a splitted sorted array + Thought it was interesting. + If there are duplicate elements, it is not guarantee that the index return + is the smallest index.**/ + +#include +#include +#include +#include + +int generate_random_number(int upper_bound); +void print_array(int array[], int n); +int binary_search(int array[], int lo, int hi, int val); +int splitted_array_search(int split_array[], int lo, int hi, int val, int n); + +int main(int argc, char** argv){ + int n; + int upper_bound; + // Input checking. Could've used a loop, but I'm not bothered :p + if(argc == 3){ + char* endp; + char* endp2; + int val = strtol(argv[1], &endp, 10); + int val2 = strtol(argv[2], &endp2, 10); + if (!*endp && !*endp2){ + n = val; + upper_bound = val2; + }else{ + std::cout << "Usage: ./split_array val1 val2"<< std::endl; + std::cout << "val1 is the length of the array, int" << std::endl; + std::cout << "val2 is the upper bound of the random number (exclusive), int" << std::endl; + return 1; + } + }else{ + std::cout << "Usage: ./split_array val1 val2"<< std::endl; + std::cout << "val1 is the length of the array, int" << std::endl; + std::cout << "val2 is the upper bound of the random number (exclusive), int" << std::endl; + return 1; + } + // Randomisation + srand (time(NULL)); + + int array[n]; + for(int i=0;i=0) + std::cout << val << " is at index " << pos << std::endl; + else + std::cout << "Value not found" << std::endl; + +} + +int generate_random_number(int upper_bound){ + return rand() % upper_bound; +} + +void print_array(int array[], int n){ + for(int i=0;i lo as the range specified is sorted + if( split_array[lo] < split_array[hi]) + return binary_search(split_array, lo, hi, val); + //std::cout << lo << " " << hi << std::endl; + + int mid = (lo+hi)/2; + // Get lucky + if (split_array[mid] == val) + return mid; + + // Check which side the the mid and query val are at + // false for left, true for right + // This is exploiting the fact that the right side is smaller than the left + bool mid_side, val_side; + mid_side = split_array[mid] < split_array[0]; + val_side = val < split_array[0]; + + // Recurse search, but reduce the range accordingly + if(mid_side == val_side){ + if (split_array[mid]val) + hi = mid-1; + else + lo = mid+1; + } + return -1; +} diff --git a/split_array_visual.cc b/split_array_visual.cc new file mode 100644 index 0000000..adafd72 --- /dev/null +++ b/split_array_visual.cc @@ -0,0 +1,167 @@ +/** This is a command line visualiser of the search + Please use a small number of array for this, otherwise it will break the printing. + This is not guarantee to work on all OS. Works on linux.**/ + +#include +#include +#include +#include +#include + +int generate_random_number(int upper_bound); +void print_array(int array[], int n); +int binary_search(int array[], int lo, int hi, int val, int n); +int splitted_array_search(int split_array[], int lo, int hi, int val, int n); +void print_search(int split_array[], int lo, int hi, int current, int n); + +int main(int argc, char** argv){ + int n; + int upper_bound; + // Input checking. Could've used a loop, but I'm not bothered :p + if(argc == 3){ + char* endp; + char* endp2; + int val = strtol(argv[1], &endp, 10); + int val2 = strtol(argv[2], &endp2, 10); + if (!*endp && !*endp2){ + n = val; + upper_bound = val2; + }else{ + std::cout << "Usage: ./split_array val1 val2"<< std::endl; + std::cout << "val1 is the length of the array, int" << std::endl; + std::cout << "val2 is the upper bound of the random number (exclusive), int" << std::endl; + return 1; + } + }else{ + std::cout << "Usage: ./split_array val1 val2"<< std::endl; + std::cout << "val1 is the length of the array, int" << std::endl; + std::cout << "val2 is the upper bound of the random number (exclusive), int" << std::endl; + return 1; + } + // Randomisation + srand (time(NULL)); + + int array[n]; + for(int i=0;i=0) + std::cout << val << " is at index " << pos << std::endl; + else + std::cout << "Value not found" << std::endl; + +} + +int generate_random_number(int upper_bound){ + return rand() % upper_bound; +} + +void print_array(int array[], int n){ + for(int i=0;i lo as the range specified is sorted + if( split_array[lo] < split_array[hi]) + return binary_search(split_array, lo, hi, val, n); + + print_search(split_array, lo, hi, -1, n); + int mid = (lo+hi)/2; + print_search(split_array, lo, hi, mid, n); + // Get lucky + if (split_array[mid] == val) + return mid; + + // Check which side the the mid and query val are at + // false for left, true for right + // This is exploiting the fact that the right side is smaller than the left + bool mid_side, val_side; + mid_side = split_array[mid] < split_array[0]; + val_side = val < split_array[0]; + + // Recurse search, but reduce the range accordingly + if(mid_side == val_side){ + if (split_array[mid]val) + hi = mid-1; + else + lo = mid+1; + } + return -1; +} + +void print_search(int split_array[], int lo, int hi, int current, int n){ + for(int i=0; i