c_cpp 排序。暴露编程访谈的例子。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 排序。暴露编程访谈的例子。相关的知识,希望对你有一定的参考价值。

// Problem: Given a vector of objects which represent employees. Using standard library sorting routine, sort the vector 
// so it is ordered alphabetically by surname and then by given name as in a company phone book.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>    // sort, transform

// Class Employee implemented with rule of zero.
class Employee{
private:
  std::string givenname;
  std::string surname;
public:
  Employee(std::string givenname_, std::string surname_) : 
    givenname(givenname_), surname(surname_) {
      std::transform(surname.begin(), surname.end(), surname.begin(), ::tolower);
      std::transform(givenname.begin(), givenname.end(), givenname.begin(), ::tolower);             
      }
  
  std::string getGivenname() const{
    return givenname;
  }
  std::string getSurname() const {
    return surname;
  }
};


// Compare Function class
class NameCompare{
public:
  bool operator()(Employee& e1, Employee& e2) const {        
    int cmpvalue = e1.getSurname().compare(e2.getSurname());    // std::string::compare 

    // If surname is same
    if(cmpvalue == 0){
      cmpvalue = e1.getGivenname().compare(e2.getGivenname());
    }
    if(cmpvalue < 0)
      return true;
    else
      return false;
}
};

template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec){
  for (auto& el : vec){    // el is a const T object
    os << el.getSurname() << ' ' << el.getGivenname() << '\n';
  }
  return os;
}

int main()
{
  std::vector<Employee> employee;
  
  employee.emplace_back("Deepak", "Gurung");
  employee.emplace_back("Paul", "Robinson");
  employee.emplace_back("Henry", "Robinson");
  employee.emplace_back("Patrick", "Johns");
  employee.emplace_back("Daniel", "Fergeuson");    
  
  std::cout << "Before sorting:\n";
  std::cout << employee << '\n';
  
  std::sort(employee.begin(), employee.end(), NameCompare{});
  
  std::cout << "After sorting:\n";
  std::cout << employee << '\n';
}
// in-place quick sort with O(nlogn) and worst case O(n^2)
// This follows STL's iterator style value are sorted in range [first, last).

#include <iostream>
#include <vector>
#include <algorithm>    // iter_swap
                        // for testing: for_each, is_sorted
#include <iterator>     // for testing: begin, end


template<class RandIt>
void quick_sort(RandIt first, RandIt last){
  
  size_t length = last - first;
  if( length < 2)
    return; 
  auto pivot = first + length/2;
  auto pivotvalue = *pivot;
  
  auto left = first;
  auto right = last-1;
  
  while(left <= right){
    // Find the leftmost value greater than or equal to the pivot
    while(*left < pivotvalue) ++left;
    // Find the rightmost value less than or equal to the pivot
    while(*right > pivotvalue) --right;
    // If the values are in wrong side of pivots, swap them
    if(left <= right){
      std::iter_swap(left, right);
      ++left;
      --right;
    }
  }
  quick_sort(first, right+1);
  quick_sort(left, last);
}


// Test function
template<class It>
void test_quick_sort(It first, It last){
  std::for_each(first, last, [](auto& v) {
    quick_sort(std::begin(v), std::end(v));
    std::cout << std::boolalpha << std::is_sorted(std::begin(v), std::end(v)) << ',';
    });
}

int main(){
  auto empty = std::vector<int> {};
  auto singleton = std::vector<int> { 1 };
  auto doubleton = std::vector<int> { 1, 2 };
  auto random = std::vector<int> { 5, 1, 3, 4, 8, 7, 2, 9, 0, 6 };
  auto sorted = std::vector<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  auto reversed = std::vector<int> { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
  auto nearly_sorted = std::vector<int> { 0, 1, 3, 2, 4, 5, 7, 6, 8, 9 };
  auto few_unique = std::vector<int> { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 };
  
  auto inputs = std::vector<std::vector<int>> { empty, singleton, doubleton, 
    random, sorted, reversed, nearly_sorted, few_unique };
  
  test_quick_sort(std::begin(inputs), std::end(inputs));
  
}
// Merge sort simple.
// Use iterator to interface. 
// Remember merge requires random access operator ([]) and O(n) additional memory. 

#include <iostream>
#include <vector>
#include <algorithm>    // for testing: for_each, is_sorted
#include <iterator>     // for testing: begin, end



template<class RandIt1, class RandItLeft, class RandItRight>
void merge_(RandIt1 destIt, RandItLeft left_first, RandItLeft left_last, RandItRight right_first, RandItRight right_last){
  
  size_t lind = 0;
  size_t rind = 0;
  
  size_t lsize = left_last - left_first;
  size_t rsize = right_last - right_first;
  
  // Merge arrays while there are elements in both
  while (lind < lsize && rind < rsize){
    if(*(left_first + lind) <= *(right_first + rind)){
      *destIt = *(left_first + lind);
      ++destIt;
      ++lind;
    } else {
      *destIt = *(right_first + rind);
      ++destIt;
      ++rind;
    }
  }
  
  // Copy rest of whichever array remains
  while( lind < lsize){
    *destIt = *(left_first +lind);
    ++destIt;
    ++lind;
  }
  while( rind < rsize){
    *destIt = *(right_first + rind);
    ++destIt;
    ++rind;
  }
  return;
}


template<class RandIt>
void merge_sort(RandIt first, RandIt last){
  size_t length = last - first;
  if(length < 2)
    return;
  size_t middle = length/2;
  
  // deduce type of element of iterator
  using value_type = typename std::iterator_traits<RandIt>::value_type;
  
  std::vector<value_type> left(first, first + middle);
  std::vector<value_type> right(first + middle, last);
  
  //Sort each sub vector, then merge the result.
  merge_sort(left.begin(), left.end());
  merge_sort(right.begin(), right.end());

  merge_(first, left.begin(), left.end(), right.begin(), right.end());
}

template<class RandIt>
void test_merge_sort(RandIt first, RandIt last){
  std::for_each(first, last, [](auto& v) {
    merge_sort(std::begin(v), std::end(v));
    std::cout << std::boolalpha << std::is_sorted(std::begin(v), std::end(v)) << ',';
    });
}

int main(){
  auto empty = std::vector<int> {};
  auto singleton = std::vector<int> { 1 };
  auto doubleton = std::vector<int> { 1, 2 };
  auto random = std::vector<int> { 5, 1, 3, 4, 8, 7, 2, 9, 0, 6 };
  auto sorted = std::vector<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  auto reversed = std::vector<int> { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
  auto nearly_sorted = std::vector<int> { 0, 1, 3, 2, 4, 5, 7, 6, 8, 9 };
  auto few_unique = std::vector<int> { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 };
  
  auto inputs = std::vector<std::vector<int>> { empty, singleton, doubleton, 
    random, sorted, reversed, nearly_sorted, few_unique };
  
  test_merge_sort(std::begin(inputs), std::end(inputs));
}
// Merge sort simple.
// Remember merge requires random access operator ([]) and O(n) additional memory. 

#include <iostream>
#include <vector>
#include <algorithm>    // for testing: for_each, is_sorted
#include <iterator>     // for testing: begin, end

template<class T>
void merge(std::vector<T>& dest, std::vector<T>& left, std::vector<T>& right){
  size_t dind = 0;
  size_t lind = 0;
  size_t rind = 0;
  
  size_t lsize = left.size();
  size_t rsize = right.size();
  
  while (lind < lsize && rind < rsize){
    if(left[lind] <= right[rind]){
      dest[dind++] = left[lind++];
    } else {
      dest[dind++] = right[rind++];
    }
  }
  while( lind < lsize){
    dest[dind++] = left[lind++];
  }
  while( rind < rsize){
    dest[dind++] = right[rind++];
  }
  return;
}


template<class T>
void merge_sort( std::vector<T>& data){
  size_t length = data.size();
  if(length < 2)
    return;
  
  size_t middle = length/2;
  
  std::vector<T> left(data.begin(), data.begin() + middle);
  std::vector<T> right(data.begin() +middle, data.end());
  
  merge_sort(left);
  merge_sort(right);
  
  merge(data, left, right);
}


// Test function
template<class It>
void test_merge_sort(It first, It last){
  std::for_each(first, last, [](auto& v) {
    merge_sort(v);
    std::cout << std::boolalpha << std::is_sorted(std::begin(v), std::end(v)) << ',';
    });
}

int main(){
  auto empty = std::vector<int> {};
  auto singleton = std::vector<int> { 1 };
  auto doubleton = std::vector<int> { 1, 2 };
  auto random = std::vector<int> { 5, 1, 3, 4, 8, 7, 2, 9, 0, 6 };
  auto sorted = std::vector<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  auto reversed = std::vector<int> { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
  auto nearly_sorted = std::vector<int> { 0, 1, 3, 2, 4, 5, 7, 6, 8, 9 };
  auto few_unique = std::vector<int> { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 };
  
  auto inputs = std::vector<std::vector<int>> { empty, singleton, doubleton, 
    random, sorted, reversed, nearly_sorted, few_unique };
  
  test_merge_sort(std::begin(inputs), std::end(inputs));
}

以上是关于c_cpp 排序。暴露编程访谈的例子。的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 递归。使用编程访谈中提到的算法进行编码曝光。

编程人生:15位软件先驱访谈录 PDF下载

需求获取常见的方法是进行客户访谈,结合你的实践谈谈会遇到什么问题,你是怎么解决的?

编程大师访谈录01----查尔斯.西蒙尼

算法 - 我可以使用内置实用程序函数进行在线编码访谈和挑战吗? [关闭]

一个热爱编程的82岁老太太:2008年图灵奖得主Barbara Liskov访谈录