下面代码中使用自定义的高精度计时器,统计两种方案消耗时间。
/*
编写一个高效率函数来找出一个字符串中第一个无重复字符.例如:”total”中的o,”teeter”中的r.
要求算法效率优于O(n2).
字符串中的字符均存在于ASCII表中。
*/
#include <iostream>
#include "StopwatchTime.h" // 计时接口
#define ASCII_LENGTH 256
using namespace std;
// 思路1
// 时间复杂度:Q(n2)
// 查找的方法,耗时较多
// 将第i个字符与其后的第i+1至最后一个字符一一比较,并记录每个字符是否重复
char findStr1(const char* str)
{
int len = strlen(str);
// 保证数组的大小大于len
int count[500] = { 0 };
CStopwatchTime stopwatchtime; // 计时
for (int i = 0; i < len; i++)
{
for (int j = i + 1; j < len; j++)
{
if (str[i] == str[j])
{
// 如果在第i+1到最后的字符中间找到了与第i个字符一样的字符,直接跳出这个循环
count[i] = 1;
break;
}
}
}
for (int n = 0; n < len; n++)
{
if (count[n] <= 0)
{
std::cout << "findStr1 耗时: " << stopwatchtime.NowInMicro() << "us" << std::endl;
return str[n];
}
}
return '\0';
}
// 思路2
// 时间复杂度:Q(n)
// 创建一个大于或等于ASCII表长度的空数组A
// 先遍历字符串,对ASCII表中每个字符在字符串中出现的次数进行计数,将计数存在空的数组中
// 再遍历字符串,并判断数组A中当前字符的计数值是否为1
// 第一个被遍历到计数为1的字符就是所求结果。
char findStr2(const char* str)
{
// 256表示ASCII表的长度
int p[ASCII_LENGTH] = { 0 };
int i = 0;
CStopwatchTime stopwatchtime; // 计时
while (str[i] != '\0')
{
p[str[i]]++;
i++;
}
for (i = 0; str[i] != '\0'; i++)
{
if (p[str[i]] == 1)
{
std::cout << "findStr1 耗时: " << stopwatchtime.NowInMicro() << "us" << std::endl;
return str[i];
}
}
return '\0';
}
int main()
{
std::cout << "请输入字符串:" << std::endl;
char strText[10000];
std::cin >> strText;
cout << "findStr1: " << findStr2(strText) << endl;
cout << "findStr2: " << findStr2(strText) << endl;
while (getchar() != '0');
return 0;
}