No. 13 - First Character Appearing Only Once

No. 13 - First Character Appearing Only Once


Problem: Implement a function to find the first character in a string which only appears once.
For example: It returns ‘b’ when the input is “abaccdeff”.

Analysis: Our native solution for this problem may be scanning the input string from its beginning to end. We compare the current scanned character with every one behind it. If there is no duplication after it, it is a character appearing once. Since it compares each character with O(n) ones behind it, the overall time complexity is O(n 2) if there are n characters in a string.

In order to get the numbers of occurrence times of each character in a string, a data container is needed. It is required to get and update the occurrence time of each character in a string, so the data container is used to project a character to a number. Hash tables fulfill this kind of requirement. We can implement a hash table, in which keys are characters and values are their occurrence times in a string.

It is necessary to scan strings twice: When a character is visited, we increase the corresponding occurrence time in the hash table during the first scanning. In second round of scanning, whenever a character is visited we also check its occurrence time in the hash table. The first character with occurrence time 1 is the required output.

Hash tables are complex, and they are not implemented in the C++ standard template library. Therefore, we have to implement one by ourselves.

Characters have 8 bits, so there only 256 variances. We can create an array with 255 numbers, in which indexes are ASCII values of all characters, and numbers are their occurrence times in a string. That is to say, we have a hash table whose size if 256, with ASCII values of characters as keys.

It is time for programming after we get a clear solution. The following are some sample code:

char FirstNotRepeatingChar( char* pString)
{
     if(pString == NULL)
         return  '\0';

     const  int tableSize = 256;
     unsigned  int hashTable[tableSize];
     for( unsigned  int i = 0; i<tableSize; ++ i)
        hashTable[i] = 0;

     char* pHashKey = pString;
     while(*(pHashKey) !=  '\0')
        hashTable[*(pHashKey++)] ++;

    pHashKey = pString;
     while(*pHashKey !=  '\0')
    {
         if(hashTable[*pHashKey] == 1)
             return *pHashKey;

        pHashKey++;
    }

     return  '\0';
}

In the code above, it costs O(1) time to increase the occurrence time for each character. The time complexity for the first scanning is O(n) if the length of string is n. It takes O(1) time to get the occurrence time for each character, so it costs O(n) time for the second scanning. Therefore, the overall time it costs is O(n).

In the meantime, an array with 256 numbers is created, whose size is 1K. Since the size of array is constant, the space complexity of this algorithm is O(1).

The author Harry He owns all the rights of this post. If you are going to use part of or the whole of this ariticle in your blog or webpages,  please add a referenced to http://codercareer.blogspot.com/. If you are going to use it in your books, please contact me (zhedahht@gmail.com) . Thanks. 

Q21: Which of the following is a valid user-defined output stream manipulator header? a. ostream& tab( ostream& output ) b. ostream tab( ostream output ) c. istream& tab( istream output ) d. void tab( ostream& output ) Q22: What will be output by the following statement? cout << showpoint << setprecision(4) << 11.0 << endl; a. 11 b. 11.0 c. 11.00 d. 11.000 Q23: Which of the following stream manipulators causes an outputted number’s sign to be left justified, its magnitude to be right justified and the center space to be filled with fill characters? a. left b. right c. internal d. showpos Q24: Which of the following statements restores the default fill character? a. cout.defaultFill(); b. cout.fill(); c. cout.fill( 0 ); d. cout.fill( ' ' ); Q25: When the showbase flag is set: a. The base of a number precedes it in brackets. b. Decimal numbers are not output any differently. c. "oct" or "hex" will be displayed in the output stream. d. Octal numbers can appear in one of two ways. Q26: What will be output by the following statements? double x = .0012345; cout << fixed << x << endl; cout << scientific << x << endl; a. 1.234500e-003 0.001235 b. 1.23450e-003 0.00123450 c. .001235 1.234500e-003 d. 0.00123450 1.23450e-003 Q27: Which of the following outputs does not guarantee that the uppercase flag has been set? a. All hexadecimal numbers appear in the form 0X87. b. All numbers written in scientific notation appear the form 6.45E+010. c. All text outputs appear in the form SAMPLE OUTPUT. d. All hexadecimal numbers appear in the form AF6. Q28: Which of the following is not true about bool values and how they're output with the output stream? a. The old style of representing true/false values used -1 to indicate false and 1 to indicate true. b. A bool value outputs as 0 or 1 by default. c. Stream manipulator boolalpha sets the output stream to display bool values as the strings "true" and "false". d. Both boolalpha and noboolalpha are “sticky” settings.
05-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值