2012-05-13 46 views
4

我工作的一個編程任務,做一個函數模板,可以處理整數和雙打。我已經這樣做了,但爲了好玩,我也想讓它能夠處理字符串。這是下面的功能。我會如何去處理字符串?C++:函數模板來處理類型爲int和字符串

// This program demonstrates the QuickSort Algorithm. 
#include <iostream> 
#include <algorithm> 
#include <ctype.h> //needed for string handling? 
using namespace std; 



//********************************************************** 
// partition selects the value in the middle of the  * 
// array set as the pivot. The list is rearranged so  * 
// all the values less than the pivot are on its left  * 
// and all the values greater than pivot are on its right. * 
//********************************************************** 

template <class T> 
int partition(T set[], int start, int end) 
{ 
    int pivotValue, pivotIndex, mid; 

    mid = (start + end)/2; 
    swap(set[start], set[mid]); 
    pivotIndex = start; 
    pivotValue = set[start]; // main.cpp:28: error: cannot convert 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to 'int' in assignment 
    for (int scan = start + 1; scan <= end; scan++) 
    { 
     if (set[scan] < pivotValue) // main.cpp:31: error: no match for 'operator<' in '*(((std::string*)(((long unsigned int)scan) * 8ul)) + set) < pivotValue' 
     { 
     pivotIndex++; 
     swap(set[pivotIndex], set[scan]); 
     } 
    } 
    swap(set[start], set[pivotIndex]); 
    return pivotIndex; 
} 

//************************************************ 
// quickSort uses the quicksort algorithm to  * 
// sort set, from set[start] through set[end]. * 
//************************************************ 

template <class T> 
void quickSort(T set[], int start, int end) 
{ 
    T pivotPoint; 

    if (start < end) 
    { 
     // Get the pivot point. 
     pivotPoint = partition(set, start, end); 
     // Sort the first sub list. 
     quickSort(set, start, pivotPoint - 1); // main.cpp:56: error: no match for 'operator-' in 'pivotPoint - 1' 
     // Sort the second sub list. 
     quickSort(set, pivotPoint + 1, end); // main.cpp:58: error: no match for 'operator+' in 'pivotPoint + 1' 
    } 
} 

int main() 
{ 
    const int SIZE = 10; // Array size 
    int count;   // Loop counter 

    // create arrays of various data types 
    int array[SIZE] = {7, 3, 9, 2, 0, 1, 8, 4, 6, 5}; 
// string array[SIZE] = {"7", "3", "9", "2","7", "3", "9", "2","a","r"}; 
    double array2[SIZE] = {7.1, 3.3, 9.0, 2.7, 0.2, 1.5, 8.9, 4.5, 6.9, 5.45}; 

    // Display the int array contents. 
    cout << "Displaying the int array before sorting" << endl; 
    for (count = 0; count < SIZE; count++) 
     cout << array[count] << " "; 
    cout << endl; 

    // Sort the int array. 
    quickSort(array, 0, SIZE - 1); 

    // Display the int array contents. 
    cout << "Displaying the int array after sorting" << endl; 
    for (count = 0; count < SIZE; count++) 
     cout << array[count] << " "; 
    cout << endl << endl; 

    // Display the double array contents. 
    cout << "Diplaying the double array before sorting" << endl; 
    for (count = 0; count < SIZE; count++) 
     cout << array2[count] << " "; 
    cout << endl; 

    // Sort the double array. 
    quickSort(array2, 0, SIZE - 1); 

    // Display the int array contents. 
    cout << "Displaying the double array after sorting" << endl; 
    for (count = 0; count < SIZE; count++) 
     cout << array2[count] << " "; 
    cout << endl; 

    return 0; 
} 

由於提前,

亞當

+0

pivotValue應該有類型T,但不是int。此代碼可能不像您期望的那樣工作T = double,因爲您將類型T的值分配給第28行中的int變量 – user502144

+1

此外,pivotPoint的類型可能應爲int。看來,解決這個問題後,一切都應該起作用。 – user502144

+0

明白了@ user502144!這就是錯誤所在。謝謝! –

回答

4

如果使用std::stringT,你可能非常接近已經工作。

如果您使用char*,您需要提供一個比較函數作爲模板參數(或者有其他方式指定T的比較方法,如類型特徵類)。

而且,你不應該實現自己的swapstd::swap已經存在,並將爲某些類型做智能事情(例如,交換兩個vector是恆定時間,而不是複製向量中的每個對象)。

+0

注意:如果這是一項家庭作業,您可能會被禁止使用'std :: swap',在這種情況下請不要擔心。 :) – StilesCrisis

+1

但它應該被標記爲這樣。 – chris

+0

謝謝@StilesCrisis!我以爲我也很親密。我現在不會爲'char'擔心。用'std :: string'我以爲我可以使用現有的關係運算符。我編輯了這個問題以添加我遇到的錯誤。這些錯誤對你有意義嗎?我也刪除了交換功能。 –

1

工程在MSVC,這是一個有點寬鬆的,所以讓我知道,如果你碰到你的編譯器的問題。

該解決方案使用函子(一類/結構與operator()),這意味着該對象可以被稱爲,好像它是一個函數。它還使用模板特 - 看看,如果你刪除template < >版本的LessThanCompare會發生什麼 - char*將回落到比較指針值(給隨機的結果)。

更好的實現你可以使用一個類來把你的快速排序和旋轉功能 - 那麼你可以使用默認模板,並避免類似quickSort<char*, LessThanCompare<char*> >調用 - 你可以只說quicksort但是這變得有點超出了範圍題!

#include <iostream> 
#include <cstring> 
#include <string> 

using namespace std; 

template <class T> 
struct LessThanCompare 
{ 
    bool operator()(T lhs, T rhs) 
    { 
     return lhs < rhs; 
    } 
}; 


template < > 
struct LessThanCompare<char*> 
{ 
    bool operator()(char* lhs, char* rhs) 
    { 
     return strcmp(lhs, rhs) == -1; // Note strcmp returns -1 if lhs < rhs 
    } 
}; 

template <class T, class Comparator> 
int partition(T set[], int start, int end) 
{ 
    Comparator CompareLessThan; // Declare an instance of the Comparator 

    T pivotValue; 
    int pivotIndex, mid; // Is mid an index or a value - use descriptive names! 

    mid = (start + end)/2; 
    swap(set[start], set[mid]); 
    pivotIndex = start; 
    pivotValue = set[start]; 
    for (int scan = start + 1; scan <= end; scan++) 
    { 
     if (CompareLessThan(set[scan], pivotValue)) 
     { 
     pivotIndex++; 
     swap(set[pivotIndex], set[scan]); 
     } 
    } 
    swap(set[start], set[pivotIndex]); 
    return pivotIndex; 
} 

//************************************************ 
// quickSort uses the quicksort algorithm to  * 
// sort set, from set[start] through set[end]. * 
//************************************************ 

template <class T, class Comparator> 
void quickSort(T set[], int start, int end) 
{ 
    int pivotPoint; 

    if (start < end) 
    { 
     // Get the pivot point. 
     pivotPoint = partition<T, Comparator >(set, start, end); 
     // Sort the first sub list. 
     quickSort<T, Comparator>(set, start, pivotPoint - 1); // main.cpp:56: error: no match for 'operator-' in 'pivotPoint - 1' 
     // Sort the second sub list. 
     quickSort<T, Comparator>(set, pivotPoint + 1, end); // main.cpp:58: error: no match for 'operator+' in 'pivotPoint + 1' 
    } 
} 

int main() 
{ 
    const int SIZE = 10; // Array size 

    // Create arrays of strings 
    char* cstrArr[SIZE] = { 
     "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}; 

    std::string strArr[SIZE]; 
    for (int i = 0; i < SIZE; ++i) 
    { 
     strArr[i] = std::string(cstrArr[i]); 
    } 

    quickSort<char*, LessThanCompare<char*> >(cstrArr, 0, SIZE-1); 
    quickSort<std::string, LessThanCompare<std::string> >(strArr, 0, SIZE-1); 

    for (int i = 0; i < SIZE; ++i) 
    { 
     cout << cstrArr[i] << "\t\t" << strArr[i] << '\n'; 
    } 

    return 0; 
} 
+0

此外,關於風格,使用'的'代替''(原進口功能到名字空間'std'而後者污染了全局命名空間和可能需要的向後兼容)。就個人而言,我不會在主函數中聲明'int count'作爲循環索引 - 在儘可能小的範圍內聲明變量。任何值得使用的編譯器都會優化掉額外的'int'。 – Zero

+0

這非常接近泛型。現在擺脫數組參數,這是很好的。 – pmr

+0

是的 - 但我不想離家庭作業解決方案太遠。我認爲泛型迭代器可能太過分了! – Zero