下面代碼中使用自定義的高精度計時器,統計兩種方案消耗時間。
/*
編寫一個高效率函數來找出一個字符串中第一個無重複字符.例如:”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;
}