算法實現--找出一個字符串中第一個無重複字符

 下面代碼中使用自定義的高精度計時器,統計兩種方案消耗時間。

/*
編寫一個高效率函數來找出一個字符串中第一個無重複字符.例如:”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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章