Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:处理整数和字符串的函数模板_C++_String_Function Templates - Fatal编程技术网

C++ C++;:处理整数和字符串的函数模板

C++ C++;:处理整数和字符串的函数模板,c++,string,function-templates,C++,String,Function Templates,我正在做一个编程作业,制作一个可以处理整数和双精度的函数模板。我已经做到了,但为了好玩,我想让它也能处理字符串。下面是函数。我如何让它处理字符串 // This program demonstrates the QuickSort Algorithm. #include <iostream> #include <algorithm> #include <ctype.h> //needed for string handling? using namespace

我正在做一个编程作业,制作一个可以处理整数和双精度的函数模板。我已经做到了,但为了好玩,我想让它也能处理字符串。下面是函数。我如何让它处理字符串

// 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;
}
//此程序演示快速排序算法。
#包括
#包括
#包含//字符串处理所需的信息?
使用名称空间std;
//**********************************************************
//分区选择*中的值
//数组设置为轴。列表被重新排列,以便*
//小于轴的所有值都位于轴的左侧*
//所有大于pivot的值都在其右侧*
//**********************************************************
模板
int分区(T集[],int开始,int结束)
{
int数据透视值,数据透视索引,中间;
mid=(开始+结束)/2;
交换(设置[开始],设置[中间];
数据透视索引=开始;
pivotValue=set[start];//main.cpp:28:错误:无法在赋值中将'std::basic_string'转换为'int'

对于(int scan=start+1;scan如果您对
T
使用
std::string
,您可能已经非常接近工作了

如果使用
char*
,则需要提供一个比较函子作为模板参数(或者使用其他方法指定
T
的比较方法,如类型特征类)


此外,您不应该实现您自己的
交换
std::swap
已经存在,并且可以对某些类型执行智能操作(例如,交换两个
向量
是固定时间,而不是复制向量中的每个对象)

此解决方案使用函子(带有
运算符()
的类/结构)这意味着可以像调用函数一样调用对象。它还使用模板专门化-看看如果删除
模板
版本的
lessthanpare
-
字符*
将返回到比较指针值(给出随机结果)时会发生什么

在更好的实现中,您可以使用一个类来放置快速排序和透视函数-然后您可以使用默认模板,避免像
quicksort
那样调用-您可以说
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;
}
#包括
#包括
#包括
使用名称空间std;
模板
结构LessThanCompare
{
布尔运算符()
{
返回左侧<右侧;
}
};
模板<>
结构LessThanCompare
{
布尔运算符()(字符*lhs,字符*rhs)
{
返回strcmp(左侧,右侧)=-1;//注意,如果左侧<右侧,strcmp返回-1
}
};
模板
int分区(T集[],int开始,int结束)
{
Comparator CompareLessThan;//声明比较器的实例
T轴值;
int pivotIndex,mid;//mid是索引还是值-使用描述性名称!
mid=(开始+结束)/2;
交换(设置[开始],设置[中间];
数据透视索引=开始;
数据透视值=设置[开始];

对于(int scan=start+1;扫描注意:如果这是一项家庭作业,您可能会被禁止使用
std::swap
,在这种情况下,请不要担心。:)但是它应该这样标记。谢谢@StilesCrisis!我还以为我也很接近。我现在不想担心
char
。有了
std::string
,我想我可以使用现有的关系运算符。我已经编辑了这个问题,以添加我遇到的错误。这些错误对你有意义吗?我也知道您已经删除了交换函数。您已经混合了透视值和透视索引(至少在分区函数中).Pivot值的类型应为
T
,索引应为
int
。您使用的任何编译器都应给出从double到int的转换以及可能的数据丢失的警告-如果不是,请尝试启用此选项,因为它极大地有助于发现可能的错误!pivotValue的类型应为T,但不是int。此代码可能无法按预期工作对于T=double,因为您在第28行中为int变量分配了一个类型为T的值,所以数据透视点的类型可能也应该是int。似乎在解决此问题后,一切都应该正常工作。明白了@user502144!这就是错误所在。谢谢!另外,关于样式,请使用
而不是
(前者将函数导入命名空间
std
,而后者污染全局命名空间,可能需要向后兼容)。就我个人而言,我不会将
int count
声明为主函数中的循环索引-在尽可能小的范围内声明变量。任何值得使用的编译器都会优化掉额外的
int
。这非常接近于泛型。现在,只要去掉数组参数就好了。是的,但我不想离它太远家庭作业解决方案。我认为通用迭代器可能太过分了!