# Swordfinger offer--The first character in a string/stream that occurs only once (+3 similar solution questions)

Title 1: Find the first character in the string that appears only once. If you enter "abaccdeff", output'b'.

We see that the first possible idea for this question is to start scanning each character in the string from the beginning. When a character is accessed, compare it with each subsequent character, and if no duplicate character is found after it, the character will appear only once. If the string has n characters, then each character may be followed by O(n) The time complexity of this method is O(n2) compared to 1 character. Let's see if there is a more time-saving method.

Since the title is related to the number of occurrences of characters, can we count the number of occurrences of each character in the string? To do this, we need a data container to store the number of occurrences of each character. In this data container, you can find the number of occurrences of each character based on the character, that is, the container is used to map a character to oneThat's what the hash table is for, but because of the special nature of this topic, we don't need to use as many complex standard library templates as the characters (chars)There are 256 possible data types with a length of 8, so we created an array with a length of 256, where each character corresponds to a number in the array with its ASCII code as the subscript. The number in the array is the number of times that character occurs.

We need to scan the string twice. The first time each character is scanned, the number in the array is added to 1 at the corresponding position, and the time complexity of n characters is O(n). The second time each character is scanned, the character is determined by the number of times in the subscript position of the array corresponding to that character, and the time complexity is O(1). Therefore, the time complexity is O(n).We need an extra auxiliary array, but since the size of the array is a constant, we can think of the spatial complexity as O(1).

Code:

```char firstUniqChar(char* s){
int a[256] = {0};
char *p = s;
for( ;*s! = '\0';s++){
a[*s]++;
}
for( ;*p! = '\0';p++){
if(a[*p] == 1)
return *p;
}
return ' ';
}
```

Related topics:
1)
Define a function, enter two strings, delete all characters that appear in the second string from the first string. For example, delete the second string from the first string "We are students"To solve this problem, we can create a simple hash table that is sold as an array to store the second string. This allows us to scan through each character of the first string with O(1) Time can tell if the character is in the second string. If the length of the first string is n, the total time complexity is O(n).

```void fuctionB(char *str1,char *str2){
char help[256];
char *str0 = str1;
char *str3 = str2;

for(;*str3!='\0';str3++)
{
help[*str3]=*str3;
}

for(;*str1!='\0';str1++)
{
str3 = str2;
for(;*str3 != '\0';str3++)
{
if(help[*str3] == *str1)
delete_char1(str0,*str1);
}
}
}

void delete_char1(char *str,char target)//Remove specified characters from a string
{
char *str1 = str;
for(;*str1 != '\0';str1 ++){
if(*str1 != target)
{
*str = *str1;
str++;
}
}
*str = '\0';
}
```

2)
Defines a function to delete all repeated characters in a string. For example, enter "google" and the result is "gole" after deleting the repeated characters.Similar to the above question, we can create a simple hash table implemented with a Boolean array. The meaning of an element in an array is whether the letter corresponding to its subscript as ASCII code has already appeared in the string. First, we set all elements in the array to false. With the word "google""For example, when scanning to the first g, the ASCII code of G is 103, so we set the element with subscript 103 in the array to true. When scanning to the second g, we find that the value of the element with subscript 103 in the array is true, so we know that G has already appeared before. That is, we use O(1) Time can tell if each character has already appeared before it. If the length of the string is n, the total time complexity is O(n).

```void fuctionC(char *str)
{
bool help[256] = {false};

char *slow = str;
char *fast = str;

for(; *fast != '\0';fast ++) {
if( help[*fast] == false) {
help[*fast] = true;
*slow = *fast;
slow ++;
}
}
*slow = '\0';

}
```

3)
In English, if two words have the same letters and each letter occurs the same number of times, the two words become anaglyphs (Anagram) For example, silent and listen, evil and live are mutually mutually mutualized. Complete a function to determine if the two strings you enter are mutually mutually mutualized. We can create a simple hash table implemented with an array to count the number of occurrences of each character in the string. When each character in the first string is scanned, add 1 to the value of the item corresponding to the hash tableNext, scan the second string, subtracting 1 from the value of the item corresponding to the hash table when each character is scanned. If all the values in the hash table are 0 after the second string is scanned, the two strings become mutually anaglyphs.

```bool fuctionD(char *str1,char *str2){
int help[256] = {0};
for(;*str1 != '\0';str1++)
help[*str1]++;
for(;*str2 != '\0';str2++)
help[*str2]--;

for(int i = 0;i < 256;i++){
if(help[i] != 0)
return false;
}
return true;
}
```

Title 2:
Implement a function to find the first character in the stream that occurs only once, for example, when you read only two characters "go" from the stream, the first character that occurs only once is "g";When six characters "google" are read from the stream, the first character that appears only once is "l".

Analysis:
Characters can only be read one after another from the character stream. You can define a data container to hold the position of a character in the character stream. When a character is first read from the character stream, save its position in the character stream in the data container. When the character is read from the character stream again, it is not a character that occurs only once, so it is OKIgnored. Update the value it holds in the data container to a special value (such as a negative value). This data container can be implemented with a hash table. Use the ASCII code of the character as the key value of the hash table, and the position of the character as the value of the hash table.

```class CharStatistics
{
public:
CharStatistics() : index(0) //Position subscript initialized to 0
{
for(int i = 0; i < 256; ++i)
occurrence[i] = -1;
}

void Insert(char ch)
{
if(occurrence[ch] == -1)
occurrence[ch] = index;
else if(occurrence[ch] >= 0)
occurrence[ch] = -2;

index++; //Positional subscript passes through each character plus 1
}

char FirstAppearingOnce()
{
char ch = '\0';
int minIndex = numeric_limits<int>::max(); // Maximum value of int type allowed by compiler
for(int i = 0; i < 256; ++i)
{
if(occurrence[i] >= 0 && occurrence[i] < minIndex)
{
ch = (char) i;
minIndex = occurrence[i];
}
}

return ch;
}
private:
int occurrence[256];
int index;
};
```

In the above code, the hash table uses an array occurrenceImplementation. The element occurence in the array corresponds to the character whose ASCII code value is i. Initially, all elements in the array are initialized to -1. When a character with ASCII code i is first read from the character stream, the occurrence value is updated to its position in the character stream. When the character is read from the character stream again (occurrence[] is greater than or equal to 0)The occurrence value is updated to -2.

When we need to find the first non-repeating character among all the characters read so far from the stream, we just need to scan the entire array and find the character corresponding to the smallest value greater than or equal to 0.

Tags: C C++ string

Posted on Sun, 03 Oct 2021 12:34:00 -0400 by gintjack